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エラーが発生するため、 および への値の割り当ては失敗bazするbarため、のbazままであり、解析段階で割り当てられた値のままです。次に、代入がレスキューされ、戻り値は になります。"a"barnil[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

レスキューの優先順位でさえ、単純な割り当てが行われ、複数の割り当てが行われない理由を説明できません。

于 2013-04-08T14:08:10.623 に答える