例外:为什么添加括号会改变什么?

gma*_*tte 6 ruby exception

在Ruby如何处理内联错误处理程序时,我想了解一些事项

情况1

这是一个常见的用例

def foo
  raise Error
end

bar = foo rescue 1
# => 1
bar
# => 1
Run Code Online (Sandbox Code Playgroud)

它按预期工作.表达式foo rescue 1返回1并正确分配给bar.

案例2

Ruby允许对数组进行解析,因此这种行为看起来很奇怪.

baz = 'a'
baz, bar = foo rescue [1, 2]
# => [1, 2]
baz
# => 'a'
bar 
# => nil
Run Code Online (Sandbox Code Playgroud)

表达式返回数组[1, 2]但不解构或赋值.它完全完全跳过了作业.

案例3

但是,当您将错误包装在括号中时,解构就会起作用.

baz, bar = (foo rescue [1, 2])
# => [1, 2]
baz
# => 1
bar
# => 2
Run Code Online (Sandbox Code Playgroud)

案例4

加分:提高错误并尝试内联处理它也会跳过分配

baz = raise Error rescue 1
# => 1
baz
# => nil
Run Code Online (Sandbox Code Playgroud)

但添加括号使其有效.

编辑:

我在Ruby 1.9.3-p392和Ruby 2.0.0上测试了这个

编辑2:

我在案例中添加了标签

编辑3:

显然有些人认为这不是一个问题,所以标题可能不够明显.以下是全文问题:

为什么会出现这些不一致,为什么添加括号会改变什么呢?

saw*_*awa 1

你的情况2与此相同:

baz = 'a'
(baz, bar = foo) rescue [1, 2]
Run Code Online (Sandbox Code Playgroud)

由于foo会引发错误,因此对baz和赋值会bar失败,因此baz仍然是"a",并且bar仍然是nil,在解析阶段分配的值。然后,分配被拯救,返回值为[1, 2]

您的情况 4 与此相同:

(baz = raise Error) rescue 1
Run Code Online (Sandbox Code Playgroud)

由于赋值的右侧会引发错误,因此对 的赋值会baz失败,并且baz仍将是nil在解析阶段分配的 。然后,分配被拯救,返回值为1

  • 那么这一切都归结为流程控制与赋值运算符的优先级? (2认同)