2010-01-11 56 views
0

人,我今天剥离洋葱层,反正这里的代码红宝石class_eval和产量

class MyClass 
    def initialize(dynamic_methods) 
    @arr = Array.new(dynamic_methods) 
    @arr.each { |m| 
     self.class.class_eval do 
     define_method(m) do 
      "<#{yield self if block_given?}>" 
     end 
     end 
    } 
    end 
end 

tmp = MyClass.new ['method1', 'method2', 'method3'] 
tmp.method1 do |t| 
    "here" 
end 

我的问题是,我试图访问“这里” define_method(米)范围内时,该方法正在执行,而不是创建时。当前的声明“<#{yield self if if block_given?}>”并不能给我这样的结果。如果您想知道,我必须保持代码的这部分,但我可以对MyClass进行所有更改。

tmp = MyClass.new ['method1', 'method2', 'method3'] 
tmp.method1 do |t| 
    "here" 
end 

任何人都可以帮助语法?在此先感谢您的帮助。

UPDATE:请参阅下面我的回答。

回答

1

尝试更换

define_method(m) do 
    "<#{yield self if block_given?}>" 
end 

define_method(m) do |&block| 
    "<#{block.call if block}>" 
end 

这应该1.8.7和后续工作。你也可以尝试使用module_eval

self.class.module_eval %Q{ 
    def #{m}(&block) 
    "<\#{block.call if block}>" 
    end 
} 
+0

它适用于1.8.7,但不能与早期版本。 – mxgrn

+0

不幸的是,你是对的,我在1.8.6上,它阻塞(语法错误)on&block。 – Bob

+0

在您可能投降'module_eval'这种情况下,需要一个字符串: module_eval%Q {DEF#{M}(块) “<#{block.call如果块}>” 端} – mxgrn

0

随着大量的来自谢尔盖的反馈和我自己的一些修修补补,我设法得到它的工作

class MyClass 
    def initialize(dynamic_methods) 
    @arr = Array.new(dynamic_methods) 
    @arr.each { |m| 
     self.class.module_eval %Q{ 
     def #{m}(&block) 
      yield(self) if block_given? 
     end 
     end 
    } 
    end 
end 

tmp = MyClass.new ['method1', 'method2', 'method3'] 
tmp.method1 do |t| 
    "here" 
end 

正如你所知道的,也有一些对谢尔盖的建议稍作调整,谢谢你的帮助谢尔盖。