Twitter以上ブログ以下

ただの読み物

ruby の Struct でキーワード引数を使って初期化する

背景

class Point < Struct.new(:x, :y); end

Point.new(x: 1, y: 2)

みたいなことをしたかった。

結論

class Point < Struct.new(:x, :y)
  def initialize(x:, y:)
    super(x, y)
  end
end

なぜ?

似たような class OpenStruct (Ruby 2.4.0) ならばできるが、OpenStructは #freeze をしないとAttributesが動的に増やせてコワイ。Hashと何が違うねん、みたいな気持ちになる

実際には異なるけどそれはそれ

でもOpenStructは便利で、 OpenStruct.new(x: 1, y: 2) ってできる。引数の順番を約束しなくてもよいので便利。 Structでもそうしたい。HashのKey:valueは取り出したときの順序を保証してないので、適当にぶち込むと謎のエラーになったりする可能性がある。

これをどうにか、静的な構造体として定義しつつ、引数の順序は問わずにいい感じにぶちこみたかった。

というわけで完成したのが結論のコード