y = lambda { z }
z = 9
y.call
=> NameError: undefined local variable or method `z' for main:Object
y = lambda { z }
y.call
=> 9
我认为拥有一个 block 的想法是推迟 block 内代码段的执行。你能解释一下吗?
最佳答案
lambda
创建所谓的 lexical closure ,这意味着它捕获对封闭环境的引用,并且可以使用在创建闭包时范围内的变量。
y = lambda { z } # Woops! There's no variable named `z`!
在创建闭包之后是否创建一个名为z
的变量并不重要;闭包的想法是在特定时刻捕获环境。
理论上,您可能希望在创建该 lambda 时出现错误,因为可以对其进行分析并确定将取消引用尚 undefined variable 。但是,Ruby 不是这样工作的;只有在评估代码时,您才会收到试图访问 undefined variable 的错误。
当您创建第二个闭包时,几行之后,那个闭包确实捕获了 z
存在的环境:
y = lambda { z } # This closure is broken and can't be fixed
z = 9
y = lambda { z } # This is a new closure, and `z` is accessible within it
我认为拥有一个 block 的想法是推迟 block 内代码段的执行。
有点像,但它与简单地从 lambda 中复制和粘贴代码并在调用它时对其求值不同。 eval
字符串可以做到这一点:
y = "z"
z = 9
eval(y)
# => 9
同样,闭包的思想是它捕获代码和环境。
关于ruby - block 第一次不识别变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16201433/