在Ruby中遇到了一种奇怪的行为.不知道这只是我.我在ruby 2.3.3上.这是日志.按顺序操作它们,你应该能够重现它.
[1] pry(main)> a &&= nil.a
=> nil
[2] pry(main)> a &&= 1.to_s
=> nil
[3] pry(main)> a = 1 && 1.to_s
=> "1"
[4] pry(main)> a &&= 1.to_s
=> "1"
[5] pry(main)> a &&= nil.a
NoMethodError: undefined method `a' for nil:NilClass
from (pry):5:in `__pry__'
Run Code Online (Sandbox Code Playgroud)
编辑:
在SO上有一个类似的问题.还有一篇试图解释它的博客文章.但我不认为他们会解释它.
在SO线程中,它表示&&=是一个快捷方式x = x && y if x.但考虑一下:
num = 1
a &&= num.to_s
# => nil
Run Code Online (Sandbox Code Playgroud)
VS
num = 1
a = num && num.to_s if num
# => "1"
Run Code Online (Sandbox Code Playgroud)
在红宝石中,如果a未定义,a = a给你nil.x = x && y if x本身就是一个奇怪的操作.
x = x && y if x
Run Code Online (Sandbox Code Playgroud)
这应该与下面相同
if x
x = x && y
end
Run Code Online (Sandbox Code Playgroud)
但是这会引发错误,因为x没有定义.那么哪个部分首先被评估?难道x = x && y还是if x?
值得注意的是Stefan下面提到的几个关于以下属性的东西&&=:
nil如果没有显式赋值,则定义的变量采用值.a逻辑上为真,或者更具体地,如果a不是nil或者中的一个时进行评估false.a逻辑上不正确,那么右侧只需要在语法上有效,因为它不会被评估.这意味着破坏的代码nil.a在这些特定条件下是可以接受的,它将被解析,否则将被忽略.a是nil,false那么值a不会改变.一个长版本a &&= b实际上是:
a = if (a)
b
else
a
end
Run Code Online (Sandbox Code Playgroud)
哪里b可以是任何表达,包括像a &&= b &&= c
至于您的示例,这与表达式的右侧是否得到评估有关.在第一种情况下a是未定义的,所以它不会.
稍后,当您实际定义a为某些东西时,它必须执行右侧,因此您最终会进行评估nil.a并且会爆炸.
在这种情况下,您可以执行任何操作:
nil && whatever(this!, will!, not!, ever!, run!)
Run Code Online (Sandbox Code Playgroud)
它不是片状的,它的表现就像你认为的那样.&&是评估短路的那些东西之一.那是在:
a && b && c && d
Run Code Online (Sandbox Code Playgroud)
实际解释是:
if a
if b
if c
d
end
end
end
Run Code Online (Sandbox Code Playgroud)
因此,在这种表示中,显而易见的是,如果任何这些条件失败,它就会退出并跳过其余条件.
要注意的一件事是a使用&&=自动弹出存在:
local_variables
# => [:_]
a &&= true
# => nil
local_variables
# => [:a,:_]
Run Code Online (Sandbox Code Playgroud)
这不是真的&&.