2011-02-06 118 views
3

的`id`领域我有一些代码在Ruby中象下面这样: 的Ruby版本:1.8.7无法访问OpenStruct实例

hash = OpenStruct.new(:id=>123, :name=>'wenbo') 
puts "#{hash.id} -- #{hash.name}" 

D:/workspace/wmch/rubytest/lib/variable.rb:17: warning: Object#id will be deprecated; use Object#object_id 
27556896 -- wenbo 

有人可以帮助我了解如何获得123 id字段的值?

+0

即使使用1.9.2下的`ruby -w`,我也没有得到这个警告;你在运行什么风味和版本的Ruby? – Phrogz 2011-02-06 05:42:43

+0

@Phrogz 1.8.7,为该问题添加了版本信息,谢谢您的提醒。 – ywenbo 2011-02-06 05:48:16

回答

2

看起来像1.8.7下的OpenStruct的bug /限制,其中没有BlankSlate对象,这是由使用method_missing决定它是否是特殊属性的实现引起的。

这是一个类似于OpenStruct的自定义类,可以根据1.8.7的要求进行操作;随时扩展它,使其更加丰富。

class MemoStruct 
    def initialize(h=nil) 
    h.each{ |k,v| add_field(k,v) } if h 
    end 
    def add_field(name, value=nil) 
    inst = :"@#{name}" 
    (class << self; self; end).class_eval do 
     define_method(name){ instance_variable_get inst } 
     define_method("#{name}="){ |v| instance_variable_set inst,v } 
    end 
    instance_variable_set(inst,value) 
    end 
    def []=(name, value) 
    add_field(name,value) 
    end 
end 

hash = MemoStruct.new :id=>123, :name=>"Jim" 
p hash.id 
#=> 123 

hash["new_field"] = "stuff" 
p hash.new_field 
#=> stuff 
4

这个问题的答案在此blog post用这个代码简单的线条

OpenStruct.__send__(:define_method, :id) { @table[:id] } 

现在,您可以设置:身份证上的OpenStruct并没有它不理你,并呼吁:一个警告

OBJECT_ID