`

ruby处理未定义的方法

    博客分类:
  • ruby
阅读更多
关于未定义的方法,《ruby编程语言》上面说得比较詳細了,所以先引用一下:
引用

  当方法名解析算法无法找到一个方法时,它会转而去寻找一个名为method_missing的方法。当此方法被调用时,它的第一个参数是一个符号,表示无法找到的方法的名字,后面的参数都是传给本来该找到的方法的。如果在进行方法调用时附带了一个代码块,则这个代码块也会被 传递给找到的方法或method_missing。
  在kernel模块中,method_missing的默认实现不过是简单的抛出一个NoMethodError异常。如果不对这个异常进行捕获,程序将在给出一个错误消息后退出。这也是通常在调用一个不存在的方法后所期望的結果。
  为一个类定制自己的method_missing方法使你有机会处理该类实例上的任何方法调用。method_missing钩子是Ruby动态机制中最强大的工具之一,它常常被用于元编程技术。
为Hash类增加一个method_missing方法,使我们可以像方法一样对某个主键的值进行查询或设置
class Hash
  # Allow hash values to be queried and set as if they were attributes.
  # We simulate attribute getters and setters for any key.
  def method_missing(key, *args)
    text = key.to_s

    if text[-1,1] == "="               # If key ends with = set a value
      self[text.chop.to_sym] = args[0] # Strip = from key
    else                               # Otherwise...
      self[key]                        # ...just return the key value
    end
  end
end

h = {}         # Create an empty hash object
h.one = 1      # Same as h[:one] = 1
puts h.one     # Prints 1. Same as puts h[:one]



上面这段引用讲得比较清楚了,而上面这段代码的作用就是粗体部分所说的那样,针对上面代码,参数key的值为"one=",而args则是代表等号后的内容。
  之所以想关注一下这个,是因为最近看了下camping的源代码,下面的代码与上面的例子的作用相似,不过更精简:
class H < Hash
    def method_missing(m,*a)
        m.to_s=~/=$/?self[$`]=a[0]:self[m.to_s]
    end
  end

其中=~是模式匹配符,$'表示匹配以前的字符,在此文中就是等号前的内容。当然这段代码是自己改了一下,原文直接是下面这样的:
class H < Hash
    def method_missing(m,*a)
        m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super
    end
    undef id, type if ?? == 63
end

暂时没看懂那个super有什么特别的用处,因为既然是继承关系,当然可以访问父类中的方法,除非是private方法,当然下面那句代码中有??这个东西,俺也不明白到底有什么深意。
具体讨论见:
http://www.iteye.com/post/1700339
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics