在ruby && =运算符是片状?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在ruby && =运算符是片状?相关的知识,希望对你有一定的参考价值。
在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__'
编辑:
有一个similar question on SO。还有一个试图解释它的blog post。但我不认为他们会解释它。
在SO thread,它说&&=
是x = x && y if x
的捷径。但考虑一下:
num = 1
a &&= num.to_s
# => nil
VS
num = 1
a = num && num.to_s if num
# => "1"
在红宝石如果a
未定义,a = a
给你nil
。 x = x && y if x
本身就是一个奇怪的操作。
x = x && y if x
这应该与下面相同
if x
x = x && y
end
但这会引发错误,因为没有定义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
b
可以是任何表达,包括像a &&= b &&= c
这样的东西
至于您的示例,这与表达式的右侧是否得到评估有关。在第一种情况下,a
是未定义的,所以它不会。
后来当你真正将a
定义为某个东西时,它必须执行右侧,所以你最终评估nil.a
并且它会爆炸。
在这种情况下,您可以执行任何操作:
nil && whatever(this!, will!, not!, ever!, run!)
它不是片状的,它的表现就像你认为的那样。 &&
是评估短路的东西之一。那是在:
a && b && c && d
实际解释是:
if a
if b
if c
d
end
end
end
因此,在这种表示中,显而易见的是,如果任何这些条件失败,它就会退出并跳过其余条件。
需要注意的一点是a
自动使用&&=
存在:
local_variables
# => [:_]
a &&= true
# => nil
local_variables
# => [:a,:_]
&&
不是这样。
以上是关于在ruby && =运算符是片状?的主要内容,如果未能解决你的问题,请参考以下文章