在Ruby中,为什么在启动irb后,foo.nil?说未定义的错误,@ foo.nil?给出"true",然后@@ wah.nil?再次给出错误? [英] In Ruby, why after starting irb, foo.nil? says undefined error, and @foo.nil? gives "true", and @@wah.nil? gives error again?

查看:122
本文介绍了在Ruby中,为什么在启动irb后,foo.nil?说未定义的错误,@ foo.nil?给出"true",然后@@ wah.nil?再次给出错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与Ruby 1.8.7和1.9.2相同:

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?

推荐答案

在Ruby中,大多数未初始化甚至不存在的变量求值为nil.对于局部变量,实例变量和全局变量,这是正确的:

In Ruby, most uninitialized or even non-existing variables evaluate to nil. This is true for local variables, instance variables and global variables:

defined? foo       #=> nil
local_variables    #=> []
if false
  foo = 42
end
defined? foo       #=> 'local-variable'
local_variables    #=> [:foo]
foo                #=> nil
foo.nil?           #=> true

defined? @bar      #=> nil
instance_variables #=> []
@bar               #=> nil
@bar.nil?          #=> true
# warning: instance variable @bar not initialized

defined? $baz      #=> nil
$baz               #=> nil
# warning: global variable `$baz' not initialized
$baz.nil?          #=> true
# warning: global variable `$baz' not initialized

但是,对于类层次结构变量和常量却并非如此:

It is, however, not true for class hierarchy variables and constants:

defined? @@wah     #=> nil
@@wah
# NameError: uninitialized class variable @@wah in Object

defined? QUUX      #=> nil
QUUX
# NameError: uninitialized constant Object::QUUX

这是一条红鲱鱼:

defined? fnord     #=> nil
local_variables    #=> []
fnord
# NameError: undefined local variable or method `fnord' for main:Object

您在这里得到错误的原因是 not 表示统一的局部变量的值不等于nil,这是因为fnord模棱两可:可能是 /em>无参数消息发送到默认接收者(即等效于self.fnord())访问本地变量fnord.

The reason why you get an error here is not that unitialized local variables don't evaluate to nil, it is that fnord is ambiguous: it could be either an argument-less message send to the default receiver (i.e. equivalent to self.fnord()) or an access to the local variable fnord.

为了消除歧义,您需要添加一个接收器或参数列表(即使为空)以告诉Ruby这是一条消息发送:

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:

self.fnord
# NoMethodError: undefined method `fnord' for main:Object
fnord()
# NoMethodError: undefined method `fnord' for main:Object

或确保 parser (评估程序 not )在使用前解析( not 执行)一个分配,以告诉Ruby这是一个局部变量:

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:

if false
  fnord = 42
end
fnord              #=> nil

为什么实例变量与局部变量和类变量的处理方式不同?

why the instance variable treated differently than a local and class 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.

还有其他原因吗?类变量也不能那样表现吗?

is there other reasons … can't class variables behave like that too?

我不知道.例如,实例变量非常方便,因为与Java不同,例如,实例变量在类定义中声明,因此在类的每个实例中始终存在实例变量,而在Ruby中,实例变量不在任何地方声明.一经分配,它们就神奇地出现了.由于不一定要保证实例变量的存在,因此编写使用实例变量的方法如果引发异常将很痛苦.

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.

这篇关于在Ruby中,为什么在启动irb后,foo.nil?说未定义的错误,@ foo.nil?给出"true",然后@@ wah.nil?再次给出错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆