在Ruby中使用yield_method中的yield

是否可以在给定于define_method的块中生成yield关键字? 简单的例子:

class Test define_method :test do |&b| puts b # => # yield end end Test.new.test { puts "Hi!" } 

此代码在Ruby 1.8.7和1.9.0中都会产生以下错误:

test.rb:4:在`test’中:没有来自test.rb的块(LocalJumpError):8

奇怪的是b块变量!= nil但是block_given? 返回false。 有意的Ruby行为是不是通过Proc对象识别块?

编辑:关于Beerlington的回答: b.call()不是我想要的。 块变量仅用于指示实际给出块,并且在define_method中未检测到。

我需要使用yield而不是block.call

我愿意为Ruby中定义新类的方式编写一些扩展,因此当我使用扩展时,你可以接受任何用纯Ruby编写的代码。

因此,不能考虑类似的语​​义,因为这会强制我的库的用户只使用一种正确的方法来传递块。 这会破坏TIMTOWTDI规则,并且不会使我的库透明。

真实的例子

由于my_def使用define_method下面的代码可以简化为上面的代码:

 require 'my_library' class Test # client can write 'my_def' instead of 'def' since # my_library extends Class class my_def :test, "some parameter" do yield # oh no, error :( end end Test.new.test { puts "Hi!" } 

我想这就是你要找的东西:

 class Test define_method :test do |&b| b.call end end Test.new.test { puts "Hi!" } 

更多信息,请访问http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/

您不能在define_method块中使用yield 。 这是因为闭包捕获了块,观察:

 def hello define_singleton_method(:bye) { yield } end hello { puts "hello!" } bye { puts "bye!" } #=> "hello!" 

我不认为你的用户会因为你所陈述的方式而无法使用’yield’ – 语法与普通的Ruby方法定义语法完全不同,所以不太可能有任何混淆。

有关为什么不能将块隐式传递给此处的方法的更多信息: http : //banisterfiend.wordpress.com/2010/11/06/behavior-of-yield-in-define_method/