Override id on a ruby object (created using OpenStruct)
I want to convert a hash to an object using OpenStruct that has an id
property, however the resultant object#id
returns the native object id, e开发者_运维百科.g.
test = OpenStruct.new({:id => 666})
test.id # => 70262018230400
Is there anyway to override this? As at the moment my workaround isn't so pretty.
OpenStruct
uses a combination of define_method
calls inside an unless self.respond_to?(name)
check and method_missing
. This means if the property name conflicts with the name of any existing method on the object then you will encounter this problem.
tokland's answer if good but another alternative is to undefine the id
method e.g.
test.instance_eval('undef id')
You could also incorporate this into your own customised version of OpenStruct
e.g.
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
This was the classical workaround, I'd be also glad to hear a better way:
>> OpenStruct.send(:define_method, :id) { @table[:id] }
=> #<Proc:0x00007fbd43798990@(irb):1>
>> OpenStruct.new(:id => 666).id
=> 666
I've switched to using Hashery and the BasicStruct (renamed version of OpenObject in latest version, 1.4) as that allows me to do this:
x = BasicStruct.new({:id => 666, :sub => BasicStruct.new({:foo => 'bar', :id => 777})})
x.id # => 666
x.sub.id # => 777
x.sub.foo # => "bar"
精彩评论