Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在Ruby中,当a未定义时,a | | 1会抛出错误,而a=a | | 1不会?_Ruby_Exception_Undefined_Undefined Behavior - Fatal编程技术网

为什么在Ruby中,当a未定义时,a | | 1会抛出错误,而a=a | | 1不会?

为什么在Ruby中,当a未定义时,a | | 1会抛出错误,而a=a | | 1不会?,ruby,exception,undefined,undefined-behavior,Ruby,Exception,Undefined,Undefined Behavior,当a未定义时,a | | 1将抛出错误,但a=a | | 1不会。这不是有点不一致吗 irb(main):001:0> a NameError: undefined local variable or method 'a' for main:Object from (irb):1 from c:/ruby/bin/irb:12:in '<main>' irb(main):002:0> a || 1 NameError: undefined

a
未定义时,
a | | 1
将抛出错误,但
a=a | | 1
不会。这不是有点不一致吗

irb(main):001:0> a
NameError: undefined local variable or method 'a' for main:Object
        from (irb):1
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):002:0> a || 1
NameError: undefined local variable or method 'a' for main:Object
        from (irb):2
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):003:0> a = a || 1
=> 1
irb(main):001:0>a
NameError:未定义的局部变量或main:对象的方法“a”
来自(irb):1
来自c:/ruby/bin/irb:12:in''
irb(主要):002:0>a | | 1
NameError:未定义的局部变量或main:对象的方法“a”
来自(irb):2
来自c:/ruby/bin/irb:12:in''
irb(主):003:0>a=a | | 1
=> 1

执行
a | | 1
时,要求它查找未定义的
a
的值

if false
  foo = 'This will never get executed'
end
当您执行
a=a | | 1
时,您要求它查找将
a
赋值给
a
的值,该值似乎不会给出错误

所以,虽然很奇怪,但我不认为这是不一致的。

这就是你的意思吗

if !(defined? a) then
    a = 1
end
使用1作为默认值来声明值可能更简单

a
这里,您正在评估未定义的
a
。因此,您会得到一个例外

a || 1
a = a || 1
在这里,您仍然需要计算
a
,以确定布尔表达式的值。与上面一样,
a
没有定义。因此,您会得到一个例外

a || 1
a = a || 1
这里定义了
a
。它被定义为未初始化的局部变量。在Ruby中,未初始化变量的值为
nil
,因此赋值表达式的右侧值为
nil | | 1
,其值为
1
,因此赋值表达式的返回值为
1
,副作用是
a
被初始化为
1

编辑:在Ruby中定义变量和初始化变量的时间上似乎存在一些混淆。get在解析时定义,但在运行时初始化。你可以在这里看到:

 foo # => NameError: undefined local variable or method `foo' for main:Object
foo
未定义

if false
  foo = 'This will never get executed'
end
此时,定义了
foo
,即使该行永远不会执行。这一行永远不会被执行的事实是完全不相关的,因为解释器无论如何与此无关:局部变量由解析器定义,解析器显然看到这一行

foo # => nil

没有错误,因为定义了
foo
,它的计算结果为
nil
,因为它未初始化。

这是错误的
a=a | | 1
不解析为
(a=a)| | 1
。它解析为
a=(a | | 1)
,因此“将a分配给a”的结果与此无关,因为a从未分配给a。@sepp2k:我根本不想暗示这一点。对不起,我把你弄糊涂了。我相信Jörg已经解释得更清楚了。+1,尽管我认为说“它被定义为一个未初始化的局部变量”有点混乱。当您执行
var=expr
时,您并没有将
var
定义为未初始化。您将var定义为
expr
的值。只是当
expr
求值时,
var
恰好未初始化,这意味着
expr
中对
var
的任何引用都将求值为零。@sepp2k:这是两个非常独立的步骤。变量定义发生在解析器中,初始化发生在解释器中。根据Ruby实现的不同,这两个事件之间可能有很长的时间间隔。例如,在BlueRuby中,Ruby源代码被解析为BRIL(BlueRuby中间语言),当您安装Ruby程序时,BRIL被存储在数据库中。可能要过几年才会有人真正运行这个程序。一直以来,变量都已定义但未初始化。这两件事甚至可能发生在不同的机器上