4

一些未声明的变量是 nil,一些会抛出错误。怎么来的?

$ irb
1.9.3p0 :001 > asdf  # local
NameError: undefined local variable or method `asdf' for main:Object
from (irb):1
from /Users/saizai/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :002 >@asdf # instance
=> nil 
1.9.3p0 :003 >@@asdf # class
NameError: uninitialized class variable @@asdf in Object
from (irb):3
from /Users/saizai/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :004 > $asdf # global
=> nil
4

1 回答 1

5

必须始终分配类变量,否则NameError当您尝试使用它们时它们将返回 a。我目前没有关于为什么会这样的详细信息。

Instance 和 Global 变量nil即使没有赋值也会返回。-w但是,如果您使用该标志运行脚本,它们会发出警告。

但是,我确实有关于局部变量的答案。局部变量之所以如此,是因为它们前面没有任何标点符号。这意味着变量可以是变量或方法调用(因为 Ruby 不需要()在没有参数的方法调用之后)。

something # could be a variable named 'something' or a method called 'something()'

如果没有为something变量赋值,那么 Ruby 解释器假定它是一个方法调用。如果没有该名称的方法,那么它会引发NameError. 这就是您会收到此消息的原因:

NameError: undefined local variable or method 'something' for main:Object
     from (irb):1
     from path/to/Ruby/bin/irb:12 in '<main>'

因此,Ruby 解释器以这种方式处理局部变量很重要,以防万一它实际上是您所指的方法。

作为一个有趣的旁注:

有一个怪癖——当 Ruby 解释器看到该变量的赋值表达式时,变量就存在了。即使没有实际执行该分配也是如此。存在但尚未被赋值的变量被赋予默认值 nil。

意思就是:

if false
   z = "Something"
end

z.nil? #=> true
never_assigned.nil? #=> NameError

上面的引用来自 David Flanagan 和 Yukihiro Matsumoto 的 The Ruby Programming Language 第 4.2 节

于 2012-04-11T16:46:56.697 回答