Ruby的一行代码“and return”的含义

4

我最近发现了一个Ruby陷阱,但我并不完全理解。那么,有人能向我解释为什么以下两个Ruby语句不同吗-

puts "foo" and return if true

VS

if true
  puts "foo" 
  return 
end
1个回答

8

要理解像你的问题中这种一行代码,你需要记住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会发生什么。因为&&运算符比and优先级高得多,所以这是一个单行程序。
puts "foo" && bar

变成

puts( "foo" && bar )

换句话说,"foo" && bar 的值将首先计算,然后作为参数传递给 #puts 方法。因为字符串 "foo" 被认为是真值,所以执行继续到 bar,它在屏幕上打印出 "bar" 并返回 nil。你可以自己尝试一下,验证其结果。
"foo" && bar

这段代码中,nil 表示一个空值,在屏幕上会打印出一个副作用为 "bar" 的信息。

puts( "foo" && bar )

因此变成
puts( nil )

这会导致屏幕上打印出一个空行。

结论是,我们应该学习语法。Ruby的设计者采取了重要措施,使代码像书一样易读。


谢谢您的解释。但是,“用户不应该懒得学习一些小东西”的说法有点儿居高临下。 - Yoni
@Jonathan,如果有些人认为这听起来很居高临下,那我向你道歉。我自己也没有完全达到想要的流利程度。我只是想强调Matz为使编程语言更接近人类语句而付出了不计其数的努力。这是一份巨大的礼物,学习它所需的努力要比发明它小得多得多。我想说的是,用户得到的回报是如此之大,以至于学习语法的步骤将显得微不足道。我的目的是鼓励,而不是暗示不良品质。 - Boris Stitnicky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接