我最近发现了一个我不完全理解的 Ruby 问题。那么,有人可以向我解释为什么 Ruby 中的以下 2 个语句不一样吗-
puts "foo" and return if true
对比
if true
puts "foo"
return
end
最佳答案
要理解您问题中的单行代码,您需要记住 Ruby 运算符及其优先级。或者,更准确地说,是 Ruby 语法。您需要以与 Ruby 解释器完全相同的方式查看语句。它必须成为你的第二天性。现在让我们来看看你的单行本
puts "foo" and return if true
让我们先把不相关的问题分开。关键字 return
仅适用于方法或 lambda 内部,并不是您问题的真正主题。此外,尾随 if true
总是有效的,因此似乎没有必要。为了一般性地讨论您的问题,让我们定义方法 #bar
和变量 baz
def bar
puts "bar"
end
baz = true
让我们谈谈修改后的单行
puts "foo" and bar if baz
如果您记住了 Ruby 语法,您将能够完全按照 Ruby 所见将行括起来:
( puts( "foo" ) and ( bar ) ) if ( baz )
尾随 if
的行为就像一个优先级很低的运算符。只有当 baz
为真时,才会执行从开头到 if
的整行,事实确实如此。因此,
puts "foo" and bar
被执行。括起来如下:
puts( "foo" ) and ( bar )
可以看到首先执行的是puts "foo"
,在屏幕上打印foo
,返回nil
。由于 nil
是假的,运算符 and
只是返回它,而其右侧的 bar
永远不会被执行。
至于
if baz
puts "foo"
bar
end
相当于:
( puts( "foo" ); bar ) if ( baz )
可以看出区别:puts "foo"
和bar
不是由和
连接起来的,而是独立的逻辑行。第一行的返回值被丢弃,不影响第二行的执行。
最后,让我们看看将 and
替换为 &&
会发生什么。因为&&
运算符的优先级远高于and
,所以oneliner
puts "foo" && bar
成为
puts( "foo" && bar )
换句话说,"foo"&& bar
的值将首先被计算,然后作为参数传递给 #puts
方法。因为字符串 "foo"
被认为是真实的,执行继续到 bar
,它在屏幕上打印 "bar"
并返回 nil
。
"foo" && bar
是nil
,作为副作用在屏幕上打印“bar”
。
puts( "foo" && bar )
这样就变成了
puts( nil )
这会导致在屏幕上打印一个空行。
士气是那个人应该学习语法。 Ruby 设计师迈出了一大步,使代码像书一样一目了然。
关于Ruby 的 one liner "and return",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24580126/