2011-01-18 9 views
5

idプロパティを持つOpenStructを使用してオブジェクトにハッシュを変換しますが、結果のobject#idはネイティブオブジェクトIDを返します。Rubyオブジェクトの上書きID(OpenStructを使用して作成)

test = OpenStruct.new({:id => 666}) 
test.id # => 70262018230400 

これをオーバーライドする方法はありますか。現時点では、私の回避策はそれほど美しくはありません。

答えて

6

OpenStructunless self.respond_to?(name)チェックとmethod_missing内部define_method呼び出しの組み合わせを使用しています。つまり、プロパティ名がオブジェクトの既存のメソッドの名前と衝突すると、この問題が発生します。

tokland's答えいいですが別の方法はidメソッドを定義解除することです。

test.instance_eval('undef id') 
また OpenStruct例えば、独自のカスタマイズされたバージョンにこれを組み込むことができる

class OpenStruct2 < OpenStruct 
    undef id 
end 

irb(main):009:0> test2 = OpenStruct2.new({:id => 666}) 
=> #<OpenStruct2 id=666> 
irb(main):010:0> test2.id 
=> 666 
+0

、あなたはしないでくださいインスタンス変数(@table、リファクタリング可能)に依存します。 – tokland

1

これは、古典的な回避策だった、私はまた、より良い方法を聞いて喜んでいると思います:

>> OpenStruct.send(:define_method, :id) { @table[:id] } 
=> #<Proc:[email protected](irb):1> 
>> OpenStruct.new(:id => 666).id 
=> 666 
0

私はそれは私がこれを行うことができますようHasheryとBasicStruct(最新バージョンでOpenObjectの名前を変更したバージョン1.4)を使用してに切り替えました:それはいいですね

x = BasicStruct.new({:id => 666, :sub => BasicStruct.new({:foo => 'bar', :id => 777})}) 
x.id  # => 666 
x.sub.id # => 777 
x.sub.foo # => "bar" 
関連する問題