【发布时间】:2011-01-19 09:18:56
【问题描述】:
是否可以使 yield 关键字在给定给 define_method 的块内工作?简单例子:
class Test
define_method :test do |&b|
puts b # => #<Proc:...>
yield
end
end
Test.new.test {
puts "Hi!"
}
此代码在 Ruby 1.8.7 和 1.9.0 中都产生以下错误:
test.rb:4:in `test': 没有给出块 (LocalJumpError) 来自 test.rb:8
奇怪的是 b 块变量 != nil 但 block_given? 返回 false。 Ruby 是否故意不通过 Proc 对象识别块?
编辑:关于 Beerlington 的回答:b.call() 不是我想要的。块变量仅用于指示实际给定的块,在define_method中未检测到。
为什么我需要使用yield 而不是block.call
我愿意为如何在 Ruby 中定义新类的方式编写一些扩展,因此当我使用我的扩展时,应该接受您可以用纯 Ruby 编写的任何代码。
因此不能考虑相似的语义,因为这会迫使我的库的用户只使用一种正确的方式来传递块。这违反了 TIMTOWDI 规则,并且不会使我的库透明。
现实生活中的例子
下面的代码可以简化为上面的代码,因为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!"
}
【问题讨论】:
-
不回答,但相关:你不能在
define_method中测试block_given。测试块,像这里:ruby-forum.com/topic/3486000
标签: ruby metaprogramming