为什么 `return a 或 b` 在 Ruby 中是空值表达式错误?

Why is `return a or b` a void value expression error in Ruby?

这很好:

def foo
  a or b
end

这个也可以:

def foo
  return a || b
end

这个returnsvoid value expression:

def foo
  return a or b
end

为什么?它甚至没有被执行;它没有通过语法检查。 void value expression 是什么意思?

return a or b 被解释为 (return a) or b,因此 return a 的值对于计算 (return a) or b 的值是必要的,但由于 return 永远不会保留一个值(因为它从该位置转义),它不是设计为 return 原始位置的有效值。因此整个表达式留下 (some_void_value) or b,并被卡住。就是这个意思。

仅仅因为or||lower precedence,这意味着return a将在or b之前执行,因此or b无法访问

In "Does `return` have precedence to certain operators in Ruby?" which I asked, Stefan 在评论中解释说 orand 实际上是 控制流运算符 ,不应用作布尔值 运算符(分别为||&&)。

他还引用了“Using “and” and “or” in Ruby”:

and and or originate (like so much of Ruby) in Perl. In Perl, they were largely used to modify control flow, similar to the if and unless statement modifiers. (...)

他们提供了以下示例:

and

foo = 42 && foo / 2

This will be equivalent to:

foo = (42 && foo) / 2 # => NoMethodError: undefined method `/' for nil:NilClass

目标是将一个数字分配给 foo 并重新分配其值的一半。因此,and 运算符在这里很有用,因为它的优先级较低,它修改/controls 个人的正常 flow表达式:

foo = 42 and foo / 2 # => 21

它也可以用作循环中的反向if语句:

next if widget = widgets.pop

相当于:

widget = widgets.pop and next

or

useful for chaining expressions together

如果第一个表达式失败,执行第二个,依此类推:

foo = get_foo() or raise "Could not find foo!"

它也可以用作:

reversed unless statement modifier:

raise "Not ready!" unless ready_to_rock?

相当于:

ready_to_rock? or raise "Not ready!"

因此 中的 a or b 表达式:

return a or b

的优先级低于 return a,后者在执行时转义当前上下文并且不提供任何值(void value)。然后这会触发错误 (repl.it execution):

(repl):1: void value expression

puts return a or b
              ^~

由于Stefan comments,此答案成为可能。