RubyのStructは便利なのでよく使いますが、いくつか欠点があります。
- 無名Structを継承すると、スクリプトのreload時にsuperclass
mismatchエラーが出る - 同一構造のStructを定義しようとしても別なStructオブジェクトが返ってくる
- 名前付きStructの場合、Struct::St
ructName のような名前空間に定義されるので衝突が心配
これらの問題を回避するために、以下のように Struct.[] を定義することにしました。
1 def Struct.[](*members) 2 name = members.map(&:to_s).sort.map(&:upcase).join('__') 3 const_defined?(name) ? const_get(name) : new(name, *members) 4 end
これを使って
1 class Dog < Struct[:name, :age, :height, :weight] 2 end
のように利用すれば、既に定義済みの場合には定義済みのStructを参照し、そうでない場合には新たにStructを定義するようになるので、上述の問題は解決できます。
なにより、
1 Struct.new(:name, :age, :height, :weight)
と書くよりスッキリします。
posted by
genki
on Sun 7 Aug 2011
at 00:32