ruby - block 第一次不识别变量

标签 ruby lambda block

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/

相关文章:

ruby-on-rails - Active Record 减去具有不同 where 语句的两个值?

java - 如何使用 lambda 初始化字段

arrays - block 方法 - 如何一起计算数组 - ruby

html - 不能让我固定在彼此旁边的顶部导航

ruby - Rails 3.0.12 性能测试问题

Ruby:生成加起来为另一个数字的随机整数

c# - linq 和 lambda 之间实体查询的 linq 性能?

Ruby 异步网络::HTTP?

ruby - 无法在 OSX 10.10 Yosemite 上的 RVM 中安装 ruby​​ 1.9.2

java - 使用 Java(流)多线程/处理的生产者消费者