Rubyのキーワード引数はハッシュで渡せる話

タイトルの通りなんだけどRailsでparamsを渡したらうまくいかなかったのでまとめてみた.

# キーワード引数取るメソッドを定義
[24] pry(main)> def f(a: 1, b: 2)
[24] pry(main)* a + b
[24] pry(main)* end
=> nil

# キーがシンボルなハッシュはそのまま引数に渡せる
[26] pry(main)> h1 = {a: 10, b: 20}
=> {:a=>10, :b=>20}
[27] pry(main)> f(h1)
=> 30

# キーが文字列なハッシュやHashWithIndifferentAccessはだめ
[28] pry(main)> h2 = HashWithIndifferentAccess.new(h1)
=> {"a"=>10, "b"=>20}
[29] pry(main)> f(h2)
ArgumentError: wrong number of arguments (1 for 0)
from (pry):55:in `f`
[30] pry(main)> h3 = {"a" => 10, "b" => 20 }
=> {"a"=>10, "b"=>20}
[31] pry(main)> f(h3)
ArgumentError: wrong number of arguments (1 for 0)
from (pry):55:in `f`

# キーワード引数の一部のみのハッシュはあり
[32] pry(main)> h4 = {a: 30}
=> {:a=>30}
[33] pry(main)> f(h4)
=> 32

# 併用はダメ
[34] pry(main)> f(h4, b: 30)
ArgumentError: wrong number of arguments (1 for 0)
from (pry):55:in `f`

# おまけ
[37] pry(main)> def g(c, a: 1, b: 2)
[37] pry(main)* a + b + c
[37] pry(main)* end
=> nil
[41] pry(main)> g(30, h1)
=> 60