Override the identifier of a ruby ​​object (created using OpenStruct)

I want to convert a hash to an object using OpenStruct , which has a property id, however the resulting object#idreturns the identifier of the original object, e.g.

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

Is it possible to override this? At the moment, my workaround is not so pretty.

+5
source share
3 answers

OpenStructuses a combination of calls define_methodinside validation unless self.respond_to?(name)and method_missing. This means that if the property name conflicts with the name of any existing method on the object, you will run into this problem.

tokland , , , 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
+6

, :

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

I switched to using Hashery and BasicStruct (the renamed version of OpenObject in the latest version, 1.4), as this 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"
0
source

All Articles