2014-10-22 27 views
1
def errors_matching(&block) 
    m = Module.new 
    (class << m ;self; end).instance_eval do 
    define_method(:===, &block) 
    end 
    m 
end 

这让我在Ruby中定义动态救援条款,例如:动态营救条款,该代码如何工作?

begin 
    raise 'hi' 
rescue errors_matching { |e| e.class.name.include?('Runtime') } => e 
    puts "Ignoring #{e.message}" 
end 

我不明白的第一段代码。 m = Module.new然后把self(在这种情况下是主要的)放在单例类中并在其上执行instance_eval是什么?

回答

1

此:

class << m; self end 

显然是一样的:

m.singleton_class 

而且

m.singleton_class.instance_eval { define_method(:foo) {} } 

只是一样

m.define_singleton_method(:foo) {} 

所以,整个errors_matching方法只是说非常令人费解的方式:

def errors_matching(&block) 
    Module.new.tap do |m| m.define_singleton_method(:===, &block) end 
end 
+0

澄清的一句话:OP与我联系,并私下向我指出这个帖子。原始代码来自我写的Exceptional Ruby。这本书的写作大多与1.8.7兼容,其中'define_singleton_method'不存在。 “tap”在1.8.7中是全新的,而不是众所周知的。 – Avdi 2014-11-25 15:59:54