4

関数によって返される値が、呼び出すかどうかによって結果が異なるという問題が発生しました。これが予想されるのか、それともある種のパーサーエラーなのか疑問に思います。

これは、関数に渡されるブロックがdo...endインライン{...}構文ではなく構文を使用する場合にのみ発生します。次に例を示します。

arr = ["a", "b", "c"]
puts i = arr.index { |x| == "b" }
#=> 1

期待どおりですが、これは期待どおりに機能しません。

arr = ["a", "b", "c"]
puts i = arr.index do |x|
  x == "b"
end
#=> #<Enumerator:0xSomeId>

私がやればそれはうまくいくが:

arr = ["a", "b", "c"]
i = arr.index do |x|
  x == "b"
end
puts i
#=> 1

ブロックがまったく渡されなかったかのように解釈されるようです(列挙子を返すことは、arr.indexブロックを使用して呼び出す場合の予想される動作です)。これは正常ですか?この動作はどこかで説明/文書化されていますか?

4

2 に答える 2

7

do...end{...}優先順位により、ブロックは左端のメソッドに関連付けられ、ブロックは右端のメソッドに関連付けられます。2番目の例では、ブロックはに関連付けられていますがputs、これは何もしません。

この場合、奇妙な動作のように見えますがdo...end、多くのRuby DSLにクリーンで読みやすい構文を提供するのは、ブロックのこの機能です。

于 2012-08-20T01:03:53.090 に答える
2

{ ... }。よりも緊密に結合するdo ... endため、do ... endブロックはIO#puts(無視されます)に接続され、。には接続されませんArray#index

あなたがそれからparensをあなたに入れるならば、puts() callあなたは見ることができます:

puts(i = arr.index do |x| x == 'b' end)
于 2012-08-20T02:30:32.300 に答える