Ruby の Struct でオブジェクトを生成するときに位置引数とキーワード引数の両方を渡すとどうなる?

2024/01/27に公開

Ruby 3.2 から Struct ではデフォルトでキーワード引数でオブジェクトを生成できるようになりました。

User = Struct.new(:name, :age)

homu = User.new(name: "homu", age: 14)
pp homu
# => #<struct User name="homu", age=14>

また、一方で引き続き位置引数でも生成することができます。

User = Struct.new(:name, :age)

homu = User.new("homu", 14)
pp homu
# => #<struct User name="homu", age=14>

位置引数とキーワード引数の両方を渡したらどうなる?

やってみました。

User = Struct.new(:name, :age)

# 第一引数が位置引数の場合は、以降は Hash のオブジェクトとして受け取る
homu = User.new("homu", age: 14)
pp homu
# => #<struct User name="homu", age={:age=>14}>

# こういう書き方も同様
mami = User.new("hoge", name: "mami", age: 14)
pp mami
# => #<struct User name="hoge", age={:name=>"mami", :age=>14}>

と、言う感じで最初に位置引数を渡した場合は以降も位置引数として受け取るようになっています。
ちなみに『位置引数を受け取らないようにする』には keyword_init: true にすることで制御できます。

User = Struct.new(:name, :age, keyword_init: true)

# error: wrong number of arguments (given 2, expected 0) (ArgumentError)
homu = User.new("homu", 14)
GitHubで編集を提案

Discussion