Drat! - Ruby has a Double Splat - Firmafon Developers Blog

を見ました。

質問1. 仮引数の** と = {} の違いはなんでしょうか?

def f(**options)
  p options #=> {:hoge=>"AAA", :foo=>"BBB"}
end

f hoge: "AAA", foo: "BBB"

def f(options = {})
  p options #=> {:hoge=>"AAA", :foo=>"BBB"}
end

f hoge: "AAA", foo: "BBB"

の違いはなんでしょうか?

実際に試してみた例

def f(options = {})
  p options #=> nil
end

f nil

(とくに問題なし)

エラー

def f(**options)
  p options
end

f nil

`f': wrong number of arguments (1 for 0) (ArgumentError)

基準はわかりませんが、実引数に与えられた種類に応じてエラーにしてくれる場合が増えたということでしょうか?


質問2. ** と mergeメソッドとの違いは?

options = { a: 'b' }
hoge = { c: 'd', **options }
p hoge #=> {:c=>"d", :a=>"b"}

fuga =  { c: 'd'}.merge(options)
p fuga #=> {:c=>"d", :a=>"b"}

同じでしょうか?