Ruby 一段 Ruby 代码解释

runup · 2016年04月21日 · 最后由 msg7086 回复于 2016年04月26日 · 3093 次阅读

看 ruby 元编程第二版,有一段代码理解了很久看不懂,现在抛出了,求帮忙解释。p57

module Hashie
  class Mash < Hashie::Hash
    def method_missing(method_name, *args, &blk)
      return self.[](method_name, &blk) if key?(method_name)
      match = method_name.to_s.match(/(.*?)([?=!]?)$/)
      case match[2]
      when "="
        self[match[1]] = args.first
        #...
      else
        default(method_name, *args, &blk)
      end
    end
  end
end

其中两句不理解:

self.[](method_name, &blk) #[]方法是什么意思,api中没有找到
(/(.*?)([?=!]?)$/)  #(.*?)和([?=!]?)如何理解?

我自己查了蛮多资料,找不到解释的入口,求帮忙指点。

1.Hash api 有 []方法,只是不接受额外的 block 的参数。[]是一个合法的方法名,任何对象都可以定义这个方法。这里的[]很可能是 Hashie::Hash 或者 Mash 覆盖了的方法

  1. .*? non-greedy, [?=!] one of "?", "=", "!"

第一个是 Hash#[]。比如 a = Hash.new; puts a[:b] 就是调用的 Hash#[]。 第二个是正则表达式啊,如果看不懂的话就去入门一下吧。

  1. 方法定义在 Mash 类总,代码参考 https://github.com/intridea/hashie/blob/master/lib/hashie/mash.rb#L113 ,虽然 hash 也有这个方法。
  2. 就是看方法是否是 ?, =, ! 任意一个结尾

#1 楼 @serco #2 楼 @msg7086 不明白其中一个正则表达式,(/(.?)([?=!]?)$/) 其中的 (.?) 是懒惰匹配,*?是 0 次以上重复最短的部分,那么在上面的案例中中如果存在如下代码:

icecream = Hashie::Mash.new
icecream.flavor = "strawberry"

按照书中的哪里(.*?)匹配的是 flaor,但是按照我自己对定义的理解,匹配的应该空值。 我自己的理解应该有问题,能不能帮我指正一下,感谢。

#4 楼 @runup 按照你的理解,如果匹配空值,那么$怎么办?这里必须满足到结尾啊。 .*?不贪婪匹配,只是为了防止?=!也被前半部分匹配中

6 楼 已删除

.*?可以匹配任意多的字符,但是要满足$所以必须要匹配到最后才行。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号