可変長引数とデフォルト式

ちなみに、可変長引数に対してデフォルトの値(配列)を設定してみると、
def foo(a=1,*b=[1,2,3])
        puts "#{a}:#{b.inspect}"
end
./method3.rb:1: syntax error
def foo(a=1,*b=[1,2,3])
               ^
怒られた。デフォルト値に配列を使用してはいけない(というかどんな値が設定できるか)、というルールってどこかに記述されているのだろうか?リファレンスを探してみたけど、それらしい記述が見当たらない…。

配列をデフォルト式として使うことが出来ない、というわけではなく、可変長引数(*b)にデフォルト式を与えられない、のです。メソッド定義についてはプログラミング言語 Ruby リファレンスマニュアルに書かれていますが、たしかに「可変長引数にデフォルト式を与えられません」と明示的に書かれていないのでわかりづらいかもしれません。一応「文法」として以下のように書かれていて、そこにはデフォルト式を書くことが出来る場所が明示してありますが、この記述でピンと来ない人がいてもおかしくないと思います。

文法:
def メソッド名 [`(' [arg0 ['=' default0]] ... [`,' `*' rest_args] [',' '&' block_arg]`)']
  式.. (body)
[rescue [error_type,..] [=> evar] [then]
  式..]..
[else
  式..]
[ensure
  式..]
end

リファレンスマニュアルの記述はともかく、可変長引数は配列として受け取りますので、デフォルト式のようなことをしたい場合は可変長引数が空かどうか(args.empty?)を調べると良いと思います。

def foo(*args)
  if args.empty?
    [1, 2, 3]
  else
    args
  end
end
foo(:bar, :baz) # => [:bar, :baz]
foo             # => [1, 2, 3]