理解从Ruby中的procs返回
|
我想知道如何将一个块传递给一个方法,该方法将使该方法返回yield.
天真的方法不起作用: def run(&block)
block.call
end
run { return :foo } # => LocalJumpError
包装在另一个proc中具有相同的效果: def run(&block)
proc { block.call }.call
end
run { return :bar } # => LocalJumpError
所以我认为return语句绑定到当前绑定的接收者.但是,尝试使用instance_eval证明我错了: class ProcTest
def run(&block)
puts "run: #{[binding.local_variables,binding.receiver]}"
instance_eval(&block)
end
end
pt = ProcTest.new
binding_inspector = proc { puts "proc: #{[binding.local_variables,binding.receiver]}" }
puts "main: #{[binding.local_variables,binding.receiver]}"
# => main: [[:pt,:binding_inspector],main]
binding_inspector.call
# => proc: [[:pt,main]
pt.run(&binding_inspector)
# => run: [[:block],#<ProcTest:0x007f4987b06508>]
# => proc: [[:pt,#<ProcTest:0x007f4987b06508>]
pt.run { return :baz }
# => run: [[:block],#<ProcTest:0x007f4987b06508>]
# => LocalJumpError
所以问题是: >怎么做到这一点? 解决方法
只有方法有接收器. return不是一种方法: defined? return #=> "expression" 尝试将其作为方法调用不起作用: def foo send(:return,123) end foo #=> undefined method `return'
虽然instance_eval在接收器的上下文中评估块(因此您可以访问接收器实例方法和实例变量): class MyClass
def foo(&block)
@var = 123
instance_eval(&block)
end
end
MyClass.new.foo { instance_variables }
#=> [:@var]
…它不会评估当前绑定中的块(因此您无权访问任何局部变量): class MyClass
def foo(&block)
var = 123
instance_eval(&block)
end
end
MyClass.new.foo { local_variables }
#=> []
您可以使用eval,但这需要一个字符串: def foo
var = 123
eval yield
nil
end
foo { "return var * 2" }
#=> 246
或者通过将绑定传递给块(再次使用eval): def foo
var = 123
yield binding
nil
end
foo { |b| b.eval "return var * 2" }
#=> 246
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
