6

关于 Ruby 如何处理内联错误处理程序,我想了解一些事情

情况1

这是一个常见的用例

def foo
  raise Error
end

bar = foo rescue 1
# => 1
bar
# => 1

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

案例2

Ruby 允许解构数组,所以这种行为看起来很奇怪。

baz = 'a'
baz, bar = foo rescue [1, 2]
# => [1, 2]
baz
# => 'a'
bar 
# => nil

该表达式返回数组[1, 2],但不解构或分配它。它完全跳过了分配。

案例3

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

baz, bar = (foo rescue [1, 2])
# => [1, 2]
baz
# => 1
bar
# => 2

案例4

加分项:引发错误并尝试内联处理它也会跳过分配

baz = raise Error rescue 1
# => 1
baz
# => nil

但是添加括号使它起作用。

编辑

我在 Ruby 1.9.3-p392 和 Ruby 2.0.0 上对此进行了测试

编辑 2

我为案例添加了标签

编辑 3

显然有些人认为这不是一个问题,所以也许标题不够明显。这是全文的问题:

为什么会发生这些不一致,为什么添加括号会改变什么?

4

2 回答 2

1

您的案例 2 与此相同:

baz = 'a'
(baz, bar = foo) rescue [1, 2]

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

您的案例 4 与此相同:

(baz = raise Error) rescue 1

由于分配的右侧引发错误,分配baz失败,并且baz将保持为nil,在解析阶段分配。然后,赋值被解救,返回值为1.

于 2013-04-08T13:53:09.513 回答
0

更新:对不起,我的例子没有奏效。我想这是解析器中的一个错误,因为简单的分配不会遇到这个问题。

bar, baz = 1,2  # bar == 1, baz == 2
bar = foo rescue [3,4] # bar == [3,4], baz == 2
bar, baz = 1,2  # bar == 1, baz == 2
bar, baz = foo rescue [3,4] # no assignment done:  bar == 1, baz == 2

甚至救援的优先级也无法解释为什么简单的赋值完成了而 multi- 没有。

于 2013-04-08T14:08:10.623 回答