为什么未声明的Ruby本地,实例,类和全局变量具有不同的行为?

一些未声明的变量为零,有些则抛出错误.怎么会?

$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
最佳答案
必须始终分配类变量,否则在尝试使用它们时它们将返回NameError.我目前没有详细说明原因.

即使未分配实例和全局变量,它们也将返回nil.但是,如果使用-w标志运行脚本,它们将发出警告.

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

something # could be a variable named 'something' or a method called '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解释器来说,以这种方式处理局部变量非常重要,以防它实际上是您所指的方法.

作为一个有趣的旁注:

There is one quirk—a variable comes into existence when the Ruby
interpreter sees an assignment expression for that variable. This is
the case even if that assignment is not actually executed. A variable
that exists but has not been assigned a value is given the default
value nil.

意思就是:

if false
   z = "Something"
end

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

以上引用来自David Flanagan和Yukihiro Matsumoto的ruby编程语言4.2节

转载注明原文:为什么未声明的Ruby本地,实例,类和全局变量具有不同的行为? - 代码日志