【问题标题】:Override id on a ruby object (created using OpenStruct)覆盖 ruby​​ 对象上的 id(使用 OpenStruct 创建)
【发布时间】:2011-01-20 19:36:47
【问题描述】:

我想使用具有id 属性的OpenStruct 将哈希转换为对象,但是生成的object#id 返回本机对象ID,例如

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

有没有办法覆盖它?目前我的解决方法不是那么漂亮。

【问题讨论】:

    标签: ruby object


    【解决方案1】:

    OpenStructunless 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
    

    【讨论】:

    • 听起来不错,你不依赖任何实例变量(@table,可以重构)。
    【解决方案2】:

    这是经典的解决方法,我也很高兴听到更好的方法:

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

    【讨论】:

      【解决方案3】:

      我已改用 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"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 2011-02-24
        相关资源
        最近更新 更多