do end で引数リストにカッコを付けてはいけない謎の文法環境
Ruby ではメソッドに渡すブロックの表記に do end と {} の2つがあるが、その違いの一つは、do end は引数リストの括弧を省略できるということだ。次のようなテスト用のメソッドを用意して、確かめてみる。
# 渡された引数とブロック引数を配列にして返す。 def f x, &blk [:f, x, blk ? blk.call : nil ] end
f(1) do 2 end # => [:f, 1, 2] f 1 do 2 end # => [:f, 1, 2] f(1) { 2 } # => [:f, 1, 2] f 1 { 2 } # => SyntaxError
ところが、なぜか特定の文法環境でこのカッコの省略が必須になる。
p (f 1 do 2 end) # => [:f, 1, 2] p (f(1) do 2 end) # => SyntaxError
もう一回カッコで囲むとコンパイルが通る。なぜだか知らない。
p ((f(1) do 2 end)) # => [:f, 1, 2]
代入の右辺や、引数リストとしての括弧の中では問題ない。
x = (f(1) do 2 end) # => [:f, 1, 2] x = f(1) do 2 end # => [:f, 1, 2]
p(f(1) do 2 end) # => [:f, 1, 2]