Ruby a=a | | b和a | | b之间的差异
我正在阅读《实用程序员指南》(Pick Axes Book)中的编程Ruby,作者声称:Ruby a=a | | b和a | | b之间的差异,ruby,Ruby,我正在阅读《实用程序员指南》(Pick Axes Book)中的编程Ruby,作者声称: var = var || "Default Value" 以及: 我不明白这一点,因为这与我所看到的没有区别。有人能帮我吗?引用资源: 在a=a | | b中,每次运行时,a都被语句设置为某物, 而对于a | | a=b,仅当a在逻辑上为false(即。 如果为零或为假)因为| |是“短路”。也就是说,如果 | |比较的左侧是正确的,没有必要这样做 检查右侧 这基本上意味着它们的行为与开发人员类似,但在内
var = var || "Default Value"
以及:
我不明白这一点,因为这与我所看到的没有区别。有人能帮我吗?引用资源:
在a=a | | b中,每次运行时,a都被语句设置为某物,
而对于a | | a=b,仅当a在逻辑上为false(即。
如果为零或为假)因为| |是“短路”。也就是说,如果
| |比较的左侧是正确的,没有必要这样做
检查右侧
这基本上意味着它们的行为与开发人员类似,但在内部,实现与上面解释的不同
编辑:
正如评论中指出的,上述解释考虑的是a | | a=b
,而不是a | |=b
。这是一个很好的观点,阅读同一链接进一步澄清了这一点:
如果未定义a,a | | a=42将引发NameError,而a | | a=42将引发NameError
返回42。所以,它们似乎不是等价的表达式
因此,它们又不是同一条语句,因为Ruby在解析时看到赋值时就分配变量(这是a | |=42
的情况)
最后一句话,这样你就不会认为我在编造这个了:)
Ruby在解析阶段看到赋值并创建变量
在某种程度上,它不会与a | | a=42结合,即使它最终
一旦实际执行发生,其行为与后者类似
如果使用具有getter和setter的类,则差异会变得更加明显:
class Foo
def var
puts 'Foo#var called'
@var
end
def var=(value)
puts 'Foo#var= called'
@var = value
end
end
您的第一个示例导致每次调用Foo#var=
:
f = Foo.new
f.var = f.var || "Default Value"
# Foo#var called
# Foo#var= called
f.var = f.var || "Default Value"
# Foo#var called
# Foo#var= called
而在第二个示例中,Foo#var=
只被调用一次:
f = Foo.new
f.var ||= "Default Value"
# Foo#var called
# Foo#var= called
f.var ||= "Default Value"
# Foo#var called
据我所知,这两个表达式对于
var
?你能在你的问题中加上一句这本书的话,说明作者的意思吗?:-)我认为这只是两种表达方式。你们很酷。ThanksIt必须是| |=
,而不是| |=
(后者会引发语法错误)@gates Ruby的解析器不允许这样做。这就像是i+=1
(ok)和i+=1
(语法错误)这就是OP所指的吗?这个问题说明了a=a | | b
和a | |=b
之间的区别,而不是a=a | | b
和a | | a=b
之间的区别。(即,如果a
不是nil
或false
,则跳过赋值)是的,即使我没有得到a | |=b是a | | a=b,你能解释一下吗@那么,选民们能解释一下为什么这个问题没有得到解决吗@德伦米,添加编辑以澄清。你不太可能在@varevarao收到解释,但通过增加研究工作,你有我的投票权。:-)为什么在第二种情况下没有第二次调用Foo.var
?@WandMaker| |=
仅当左侧值为nil
或false
时才进行赋值f.var
最初是nil
,因此第一个f.var | |=
指定默认值“
。第二次,f.var
返回“Default value”
,因此不执行赋值。如果我没有弄错的话,一个等价的表达式将类似于f.var.tap{v | f.var=v | | Default value',除非v}
f = Foo.new
f.var ||= "Default Value"
# Foo#var called
# Foo#var= called
f.var ||= "Default Value"
# Foo#var called