Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override id on a ruby object (created using OpenStruct)

Tags:

object

ruby

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.

like image 457
DEfusion Avatar asked Jan 18 '11 14:01

DEfusion


2 Answers

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
like image 124
mikej Avatar answered Nov 14 '22 07:11

mikej


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
like image 1
tokland Avatar answered Nov 14 '22 08:11

tokland