Ruby class_eval和yield

伙计,我今天正在剥洋葱层,无论如何这里是代码

class MyClass def initialize(dynamic_methods) @arr = Array.new(dynamic_methods) @arr.each { |m| self.class.class_eval do define_method(m) do "" end end } end end tmp = MyClass.new ['method1', 'method2', 'method3'] tmp.method1 do |t| "here" end 

我的问题是,我正在尝试在执行方法时访问define_method(m)中的“here”,而不是在创建时。 当前语句“”并没有给我这个。 如果您想知道,我必须按原样保留这部分代码,但我可以对MyClass进行所有我想要的更改。

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

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

更新:请参阅下面的答案。

尝试更换

 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 } 

有了谢尔盖的很多反馈和我自己的一些修修补补,我设法让它发挥作用

 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 

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