【一人 Ruby Advent Calendar 2017】キーワード引数や Hash の渡し方や受け取り方いろいろ【24日目】

一人 Ruby Advent Calendar 2017 24日目の記事になります。
Ruby 3.0 でキーワード引数をぶっ壊すらしいのですが、現状の仕様をよく理解していないので簡単にまとめてみようかと。

Hash を渡す時に {} を省略

引数の最後が Hash 値の場合、{} を省略して書くことが出来ます。

def func a, b
    return a, b
end

# Hash 値を渡す
p func 42, { name: "homu", age: 14 }
# =>[42, {:name=>"homu", :age=>14}]

# 最後の引数が Hash 値の場合、{} を省略出来る
p func 42, name: "homu", age: 14
# =>[42, {:name=>"homu", :age=>14}]

# Hash でなくても渡せる
p func 42, 32
# =>[42, 32]

# 最後でなければエラー
# Error:syntax error, unexpected ')', expecting =>
# p func name: "homu", age: 14, 42

** で受け取る

メソッドの引数に ** を付けることで『Hash として受け取る』事を明示化することが出来ます。

def func a, **hash
    return a, hash
end

# Hash 値を渡す
p func 42, { name: "homu", age: 14 }
# =>[42, {:name=>"homu", :age=>14}]

# 最後の引数が Hash 値の場合、{} を省略出来る
p func 42, name: "homu", age: 14
# =>[42, {:name=>"homu", :age=>14}]

# Hash でなければエラー
# Error: wrong number of arguments (given 2, expected 1) (ArgumentError)
p func 42, 32

キーワード引数

以下のように引数を定義する時に『引数名: デフォルト値』と記述することでキーワード引数として定義できる。
キーワード引数はメソッドを呼び出す時に『引数名: 値』のようにして『任意の引数名に対して』引数を渡すことが出来る。

def func id, name: :homu, age: 14
    { id: id, name: name, age: age }
end

p func 1, name: :homu, age: 14
# =>{:id=>1, :name=>:homu, :age=>14}
p func 1, age: 15, name: :mami
# =>{:id=>1, :name=>:mami, :age=>15}

よくあるのが複数の引数があった場合に『一部の引数だけ渡す』みたいな時に使うことが多いですかねー。

def setting a: 1, b: 2, c: 3
    
end

# 一部の引数だけ渡す
setting a: 10
setting b: 20
setting c: 30

まとめ

  • Hash をいい感じに渡す手段はいくつかある
  • メソッドの受け取り側と渡し側でどのようにして引数を渡すのか意識する必要がある


今まで雰囲気で使っていたんですが、思ったよりも役割によって使う機能が違っている感じですねー。
もっとなんか複雑だと思っていたんですが、言われてみれば『そうかーそうやって使い分けるのかー』という印象。
Ruby 3.0 だとこのあたりをもっとよくするらしいんですが、どうなるんでしょうねえ…。

参照