在Ruby中,为什么启动irb后,foo.nil?说未定义错误,@foo.nil?给出“true”,并且@@wah.nil?又报错了?
Ruby 1.8.7 和 1.9.2 中相同:
$ irb
ruby-1.8.7-p302 > foo.nil?
NameError: undefined local variable or method `foo' for #<Object:0x3794c>
from (irb):1
ruby-1.8.7-p302 > @bar.nil?
=> true
ruby-1.8.7-p302 > @@wah.nil?
NameError: uninitialized class variable @@wah in Object
from (irb):3
为什么实例变量的处理方式与本地变量和类变量不同?
Same in Ruby 1.8.7 and 1.9.2:
$ irb
ruby-1.8.7-p302 > foo.nil?
NameError: undefined local variable or method `foo' for #<Object:0x3794c>
from (irb):1
ruby-1.8.7-p302 > @bar.nil?
=> true
ruby-1.8.7-p302 > @@wah.nil?
NameError: uninitialized class variable @@wah in Object
from (irb):3
why the instance variable treated differently than a local and class variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 Ruby 中,大多数未初始化甚至不存在的变量的计算结果为
nil
。对于局部变量、实例变量和全局变量来说是这样的:但是,对于类层次结构变量和常量来说却不是这样:
这是一个转移注意力的问题:
这里出现错误的原因是不是单位化局部变量的计算结果不会为
nil
,而是fnord
不明确:它可能是发送到的无参数消息默认接收者(即相当于self.fnord()
)或对局部变量fnord
的访问。为了消除歧义,您需要添加一个接收者或一个参数列表(即使为空)来告诉 Ruby 这是一条消息发送:
或者确保解析器(不是< /em> 求值器)在使用之前解析(不执行)一个赋值,以告诉 Ruby 它是一个局部变量:
事实上并非如此。它的处理方式与局部变量相同。类层次结构变量是行为不同的变量,局部变量、实例变量和全局变量的行为都是相同的。
我不知道。对于实例变量来说,它非常方便,因为与 Java 不同,实例变量在类定义中声明,因此对于类的每个实例始终存在,而在 Ruby 中,实例变量不在任何地方声明。一旦被分配,它们就会神奇地出现。由于实例变量不一定存在,因此如果实例变量抛出异常,那么编写使用实例变量的方法将会很痛苦。
为什么类层次结构变量不同,我不知道。也许是因为无论如何都没有人使用它们,或者因为它们通常倾向于在类主体中初始化,并且在未初始化时根本不会访问它们。
In Ruby, most uninitialized or even non-existing variables evaluate to
nil
. This is true for local variables, instance variables and global variables:It is, however, not true for class hierarchy variables and constants:
This is a red herring:
The reason why you get an error here is not that unitialized local variables don't evaluate to
nil
, it is thatfnord
is ambiguous: it could be either an argument-less message send to the default receiver (i.e. equivalent toself.fnord()
) or an access to the local variablefnord
.In order to disambiguate that, you need to add a receiver or an argument list (even if empty) to tell Ruby that it is a message send:
or make sure that the parser (not the evaluator) parses (not executes) an assignment before the usage, to tell Ruby that it is a local variable:
It's not, actually. It's treated the same as a local variable. The class hierarchy variable is the one that behaves differently, local variables, instance variables and global variables all behave the same.
I don't know. For instance variables it is very convenient, since unlike in Java, for example, where instance variables are declared in the class definition und thus always exist for every instance of the class, in Ruby, instance variables aren't declared anywhere. They just magically spring into existence, as soon as they are assigned. Since instance variables aren't necessarily guaranteed to exist, writing methods that use instance variables would be a pain if they threw exceptions.
Why class hierarchy variables are different, I have no idea. Maybe it's because nobody uses them anyway, or because they generally tend to be initialized in the class body and simply aren't accessed when they are not initialized.