我只是学习ruby并试图理解块中执行的代码范围.例如,我希望能够创建一个影响其附加方法的块,如下所示:
def test(&block) block.call() if block_given? puts "in test, foo is #{foo}" puts "in test, bar is #{bar}" end test() { foo="this is foo" bar="this is bar" }
在这种情况下,我根本不想修改块 - 我希望能够使用简单的变量引用和没有参数来编写它.只有通过在上面的例子中更改'test'方法,是否可以访问块中定义的变量?
同样,目标是保持块不被修改,但能够在块执行后从'test'中访问创建的变量.
首先,block.call()
完成后yield
,你不需要这样的&block
参数.
你通常不能做你想要的,在创建块时绑定块,在块中你可以看到当时定义的局部变量; 做你想要的最简单的方法,这不是你将如何正常使用块,是这样的:
def test() foo = yield if block_given? puts "in test, foo is #{foo}" end test() { foo="this is foo" }
但这只是副作用,因为foo
被块"返回"了.如果你这样做:
def test() foo = yield if block_given? puts "in test, foo is #{foo}" end test() { foo="this is foo" "ha ha, no foo for you" }
你会发现它做了不同的事情.
这里更神奇:
def test(&block) foo = eval "foo", block.binding puts foo block.call foo = eval "foo", block.binding puts foo end foo = "before test" test() { foo = "after test" "ha ha, no foo for you" }
这会有点工作,但如果你删除它就会中断foo = "before test"
因为foo
在块中成为局部变量而在绑定中不存在.
简介:您无法从块中访问局部变量,只能访问定义块的局部变量以及块的返回值.
即使这样也行不通:
def test(&block) eval "foo = 'go fish'", block.binding block.call bar = eval "foo", block.binding puts bar end
因为foo
在绑定中不同于块中的本地(我不知道这一点,谢谢).