##はじめに
コードリーディングをしていたら、
引数の中に「*」(アスタリスク)があったので、なんだ?と思い調べたことをまとめたいと思います。
結論から言うと、この書き方で可変長で引数を受け取ることができるのです。
要は、呼び出した引数が0の場合でもnilになるだけでエラーは出ないですし、逆に複数あったとしても全て受け取ることができるのです。
##例えば・・・
def hoge(*args)
p args
end
hoge()
# => nil
hoge(1,2,3)
# => [1, 2, 3]
hoge(1,2,dog:3,cat:4)
# => [1, 2, {:dog=>3, :cat=>4}]
というように、複数を受け取ることはもちろんのこと、ハッシュ形式の値も受け取ることができます。
ここで押さえておきたいことが、複数の値は受け取っても全て配列の中に収まるということです。
さらに、「**」とアスタリスクを二つに並べることもできます。
def hoge(**args)
p args
end
hoge(1,2,3)
# => ArgumentError: wrong number of arguments (given 3, expected 0)
hoge(1,2,dog:3,cat:4)
# => ArgumentError: wrong number of arguments (given 2, expected 0)
hoge(dog:3,cat:4)
# => {:dog=>3, :cat=>4}
どうでしょう。複数の値は受け取りますが、逆にハッシュ形式のものしか受け取らなくなりました。
そして、今度は配列の中ではなくてハッシュ形式のまま受け取っていますね。
さらに使い方を変えてみます。
def hoge(args1,args2,*args3)
p args1
p args2
p args3
end
hoge(1,2,3,4,5)
# => 1
# => 2
# => [3, 4, 5]
hoge(1,2,3,dog:4,cat:5)
# => 1
# => 2
# => [3, {:dog=>4, :cat=>5}]
通常の引数がそれぞれ1つずつ値を受け取った後、最後にまとめて*args3が受け取っています。
##extract_options!
周辺で.extract_options!
が使用されており、これも調べてみました。
def hoge(*args)
p args
p args.extract_options!
p args
end
hoge(1,2,3,4)
# => [1, 2, 3, 4]
# => {}
# => [1, 2, 3, 4]
hoge(1,2,3,dog:4,cat:5)
# => [1, 2, 3, {:dog=>4, :cat=>5}]
# => {:dog=>4, :cat=>5}
# => [1, 2, 3]
これからわかることは、extract_options!
をメソッドにすると、argsに入っているハッシュの値を奪い取ってしまうということですね。
奪い取られた後のargsには、ハッシュの値は無くなっています。
##おまけ
個人的に気になったので、引数の順番を変えて実験してみました。
def hoge(args1,*args2,args3)
p args1
p args2
p args3
end
hoge(1,2,3,4,5)
# => 1
# => [2, 3, 4]
# => 5
ふむふむ、間に置くと後ろの引数は最後の一つだけ取り出すのね。
def hoge(args1,*args2,**args3)
p args1
p args2
p args3
end
hoge(1,2,3,4,5)
# => 1
# => [2, 3, 4, 5]
# => {}
hoge(1,2,3,4,{cat:5},6)
# => 1
# => [2, 3, 4, {:cat=>5}, 6]
# => {}
この場合は、最後にハッシュ形式を置かないと受け取るものがないので空になってしまう。