简体   繁体   English

Ruby class_eval和yield

[英]Ruby class_eval and yield

Man, I'm peeling the layers of the onion today, anyway here's the code 伙计,我今天要去皮洋葱层,反正这是代码

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

My problem is that I'm trying to access "here" within define_method(m) when the method is being executed, not when created. 我的问题是我正在尝试在执行方法时而不是在创建方法时访问define_method(m)中的“ here”。 The current statement "<#{yield self if block_given?}>" doesn't give me that. 当前的语句“ <#{如果block_given会屈服于自己?}>”不会给我那句话。 And in case you are wondering, I have to keep this part of the code as is but I can make all the changes I want to MyClass. 如果您想知道,我必须保留这部分代码,但是我可以对MyClass进行所有更改。

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

Can anyone help with the syntax? 任何人都可以帮助语法吗? Thanks in advance for your help. 在此先感谢您的帮助。

UPDATE: See below for my answer. 更新:请参阅下面的我的答案。

Try replacing 尝试更换

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

with: 与:

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

This should work for 1.8.7 and up. 这应该适用于1.8.7及更高版本。 You may also try to use module_eval : 您也可以尝试使用module_eval

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

With a lot of feedback from Sergei and some tinkering on my own, I manage to get it working 在Sergei的大量反馈和我自己的帮助下,我设法使其正常运行

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

As you can tell, there are some minor tweaks to Sergei's suggestions, so thanks for all your help Sergei. 如您所知,Sergei的建议有一些细微的调整,因此感谢您对Sergei的所有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM