Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 范围令人困惑_Ruby - Fatal编程技术网

Ruby 范围令人困惑

Ruby 范围令人困惑,ruby,Ruby,我对块内变量的范围感到困惑。这项工作: f = 'new' [1,2,3].each do |n| puts f * n end #=> new newnew newnewnew 但这并不是: [1,2,3].each do |n| a ||=[] a << n end a #=>a does not exsit! [1,2,3]。每个都有| a | |=[] a不存在! 为什么会这样?请为我提供一些关于这个主题的资源。什么让人困惑 在第一个代码段中,创建了

我对块内变量的范围感到困惑。这项工作:

f = 'new'
[1,2,3].each do |n| puts f * n end
#=> new newnew newnewnew
但这并不是:

[1,2,3].each do |n|
  a ||=[]
  a << n
end
a
#=>a does not exsit!
[1,2,3]。每个都有|
a | |=[]
a不存在!
为什么会这样?请为我提供一些关于这个主题的资源。

什么让人困惑

在第一个代码段中,创建了
f
,然后执行
每个
块,它可以看到自身之外的东西(称为封闭范围)。因此它可以看到
f

在第二个代码段中,您在块内创建了一个
a
,因此它的作用域就是该块。在块之外,
a
不存在

当您引用一个名称(
a
)时,ruby将从当前作用域向外,在所有封闭的作用域中查找该名称。如果它在其中一个封闭作用域中找到它,它将使用与该名称关联的值。如果不是,它将返回到最局部的范围并在那里创建名称。随后的名称查找将生成与该名称关联的值

当一个块结束时,该作用域中的名称将丢失(值不会丢失,只会丢失名称;当垃圾收集器发现不再有名称(或任何内容)引用该值时,值将丢失,并且gc将收集该值以重用其内存)。
如果可视化是你的事情,我发现将范围看作一个楼梯是很有帮助的,在程序开始时,你站在最上面的第一步。每次输入一个块时,您都会下一步。您可以看到当前步骤上的所有内容,以及当前步骤上方步骤上的所有内容,但下面步骤上没有任何内容。当你引用一个变量名时,你会在你所处的步骤上四处寻找它。当您看到它时,您使用该值。如果你看不到它,你就看下一步。如果你看到它,你就使用这个值。你一遍又一遍地这样做,直到你看到了最上面的一步,但没有看到这个名字。如果发生这种情况,您将在您所站的步骤上创建名称(如果您正在查找指定,请为其指定一个值)。下次你寻找这个名字时,你会在你站的台阶上看到它,并在那里使用它

当一个块结束时,您可以跨上一个楼梯台阶。因为您在下面的步骤中看不到任何名称,所以您以前所在的步骤中的所有名称都将丢失

如果这对你有帮助,那就这样想吧。如果没有,就不要


1实际上,您正在进行第二步,因为您不在全局范围内,但要使用全局范围中的名称,必须在名称开头使用$。因此,在楼梯示例中,如果您要查找的名称开头有$,则直接查看顶部台阶。如果不是,你就别看那么远。然而,这是一种错误,因为程序中的所有楼梯都会共享同一个顶部台阶,这让人觉得奇怪。

很简单,在块内定义的变量在块外是看不到的(如果发生这种情况,我们会说变量泄漏了,正如这个词所暗示的,这是不好的):

map工作得更好:

a = [1,2,3].map do |n|
  n
end

无需在街区外声明
a

如果我用一个比喻,我会指一辆装有烟熏玻璃的汽车;你可以从里向外看,但不能从另一个方向看。@sawa是的,但是你有嵌套的示波器,就像车里的车一样。然后事情开始变得一团糟,就像一套俄罗斯娃娃,每一个都由烟熏玻璃制成,娃娃和礼品盒之间有全局变量。事实上,这就是它在解释器中实际实现的方式。@Mori-Omg,ruby解释器中有babushkas?!我很震惊我只是开玩笑,xoxo@Seth伟大的隐喻,对我来说有意义!还有@Mori你的娃娃真是太酷了@萨瓦谢谢你再次纠正我的问题你说得对!但我只想举例说明我不能在范围之外使用的变量
a = [1,2,3].map do |n|
  n
end