【发布时间】:2011-01-20 19:36:47
【问题描述】:
我想使用具有id 属性的OpenStruct 将哈希转换为对象,但是生成的object#id 返回本机对象ID,例如
test = OpenStruct.new({:id => 666})
test.id # => 70262018230400
有没有办法覆盖它?目前我的解决方法不是那么漂亮。
【问题讨论】:
我想使用具有id 属性的OpenStruct 将哈希转换为对象,但是生成的object#id 返回本机对象ID,例如
test = OpenStruct.new({:id => 666})
test.id # => 70262018230400
有没有办法覆盖它?目前我的解决方法不是那么漂亮。
【问题讨论】:
OpenStruct 在unless 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
【讨论】:
这是经典的解决方法,我也很高兴听到更好的方法:
>> OpenStruct.send(:define_method, :id) { @table[:id] }
=> #<Proc:0x00007fbd43798990@(irb):1>
>> OpenStruct.new(:id => 666).id
=> 666
【讨论】:
我已改用 Hashery 和 BasicStruct(在最新版本 1.4 中重命名为 OpenObject),因为这样我可以这样做:
x = BasicStruct.new({:id => 666, :sub => BasicStruct.new({:foo => 'bar', :id => 777})})
x.id # => 666
x.sub.id # => 777
x.sub.foo # => "bar"
【讨论】: