来自Ruby初学者的简单问题

时间:2014-03-29 21:56:15

标签: ruby variables

我收到以下错误消息

  

NameError:未定义的局部变量或方法a' for main:Object from (irb):2 from /usr/local/bin/irb:12:in'

如果我的代码如下:

[1,2,3].each{|x| a=x}
puts x

但是,如果我在脚本的开头放一个句子,一切都很好。

a=nil

有人会告诉我为什么' a = nil'有必要的? 谢谢!

1 个答案:

答案 0 :(得分:2)

[1,2,3].each{|x| a = x} 
puts a

您在此处创建了a。所以a只能在块内访问。外面的世界不知道谁是aa在词法上限定为阻止。因此,当您在将a引入块的外部范围之前尝试使用a时, MRI 抱怨x。如果您也尝试访问[1].each do |x| a = x local_variables # => [:x, :a] end local_variables # => [] ,那么您将从 MRI 获得相同的投诉。

a = nil
[1,2,3].each{|x| a = x} 
puts a

a

现在你在区块外创建了#each,这是顶级的。现在{ |..| ... }方法占用了一个块a。块是Ruby中的闭包,即它可以访问外部变量,这些变量是在定义块之前创建的。在块中,您可以访问您在外部定义的a并进行更新。现在,当bock将结束执行时,您可以看到x的上次更新值。 *但是,如果您尝试访问x,您将从 MRI 获得与上面相同的错误/抱怨。* - 原因是,{{ 1}}词法作用于块,你在第一时间创建它,外部作用域,即在块之外,它没有存在。

a = nil
[1].each do |x|
  a = x
  local_variables # => [:x, :a]
end

local_variables # => [:a]