👊

RubyのStructを初期化したかった...

2022/09/01に公開

経緯

とあるStructがありました。

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

これを使おうと思いました。

user = User.new(id: 1, name: 'test')
user.name
# => nil

なぜかnameがnilでした。

調査

とりあえずuserの中身を全部見てみる。

puts user
# <struct id={:id=>1, :name=>"test"}, name=nil>

ん? user.id{:id=>1, :name=>"test"} が入っている?

だるいけど公式のドキュメントを確認してみる。
https://docs.ruby-lang.org/ja/latest/class/Struct.html

keyword_init: true を指定した場合
キーワード引数で初期化することを想定した構造体になります。

なるほど、これが足りないのか...

修正

User = Struct.new(
  :id,
  :name,
  keyword_init: true, # 追加
)
user = User.new(id: 1, name: 'test')
user.name
# => "test"

nameに値が入りましたね。

それか、 keyword_init を使わずに、

User = Struct.new(
  :id,
  :name,
)
user = User.new(1, 'test') # キーワードを使わない
user.name
# => "test"

でも想定した動きになりました。

Discussion