Ruby Struct の使い方について調べた。

Ruby Struct

Struct クラスに新しいサブクラスを作って、それを返します。

サブクラスでは構造体のメンバに対するアクセスメソッドが定義されています。

dog = Struct.new("Dog", :name, :age)
fred = dog.new("fred", 5)
fred.age = 6
printf "name:%s age:%d", fred.name, fred.age
#=> "name:fred age:6" を出力します

第一引数が String の場合

String の場合、クラス名になるので、大文字で始まる必要があります。

p Struct.new("Foo", :foo, :bar)   # => Struct::Foo

第一引数が Symbol の場合

生成した構造体クラスは名前の無いクラスになります。名前の無いクラスは最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。

Foo = Struct.new(:foo, :bar)
p Foo # => Foo

ブロックを指定した場合

Struct.new にブロックを指定した場合は定義した Struct をコンテキストにブロックを評価します。また、定義した Struct はブロックパラメータにも渡されます。

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end
Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"

keyword_init: true を指定した場合

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

Point = Struct.new(:x, :y, keyword_init: true) # => Point(keyword_init: true)
Point.new(x: 1, y: 2) # => #<struct Point x=1, y=2>
Point.new(x: 1)       # => #<struct Point x=1, y=nil>
Point.new(y: 2)       # => #<struct Point x=nil, y=2>
Point.new(z: 3)       # ArgumentError (unknown keywords: z)

この中でいうと keyword_init: true オプションを使った Struct が一番使いやすくて便利そう。

かつ、単なる Hash ではなく Struct オブジェクトに値を展開するときのリファクタリングとして使える。