Переопределить идентификатор для объекта ruby ​​(созданного с помощью OpenStruct) - PullRequest
5 голосов
/ 18 января 2011

Я хочу преобразовать хеш в объект, используя OpenStruct , который имеет свойство id, однако результирующий object#id возвращает собственный идентификатор объекта, например,

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

Есть ли способ это переопределить?Поскольку на данный момент мой обходной путь не так хорош.

Ответы [ 3 ]

6 голосов
/ 18 января 2011

OpenStruct использует комбинацию define_method вызовов внутри чека unless self.respond_to?(name) и method_missing.Это означает, что если имя свойства конфликтует с именем любого существующего метода объекта, то вы столкнетесь с этой проблемой.

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
1 голос
/ 18 января 2011

Это был классический обходной путь, я также был бы рад услышать лучший способ:

>> OpenStruct.send(:define_method, :id) { @table[:id] }
=> #<Proc:0x00007fbd43798990@(irb):1>
>> OpenStruct.new(:id => 666).id
=> 666
0 голосов
/ 20 января 2011

Я переключился на использование 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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...