Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 无法访问OpenStruct实例的'id'字段_Ruby - Fatal编程技术网

Ruby 无法访问OpenStruct实例的'id'字段

Ruby 无法访问OpenStruct实例的'id'字段,ruby,Ruby,我有一些Ruby代码,如下所示: Ruby版本:1.8.7 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 有人能帮我

我有一些Ruby代码,如下所示: Ruby版本:1.8.7

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字段值吗

看起来像是1.8.7版本下OpenStruct的一个缺陷/限制,其中没有BlankSlate对象,这是由使用
method\u 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
类备忘录结构
def初始化(h=nil)
h、 每个{k,v{add_域(k,v)}如果h
结束
def add_字段(名称,值=nil)
inst=:“@#{name}”
(类123,:name=>“Jim”
p.id
#=> 123
散列[“新字段”]=“填充”
p hash.new_字段
#=>东西

这一行简单的代码回答了这个问题

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

现在,您可以在OpenStruct上设置:id,而不让它忽略您并调用:object_id并发出警告

即使使用1.9.2下的
ruby-w
,我也不会收到此警告;您运行的是什么风格和版本的ruby?@phrogz1.8.7,在问题中添加了infor版本,感谢您的提醒。不客气,请注意在我提供的代码与OpenStruct的对比中,ce是指您不能要求一个您自己没有设置的字段;如果您愿意,您可以通过
method\u missing
添加该功能。由于该类定义了方法,我建议改为使用
respond\u to?
来确定实例中是否有特定属性相反,或者,如果hash.instance_variables.include(:@catz)Cool solution,则使用
nested_struct=MemoStruct.new({:A=>{:b=>{:c=>“nested value”}})可以递归地定义结构的链式关联。然后使用
nested_struct=MemoStruct.new({:A=>{:b=>{:c=>“nested value”})可以得到“nested value”使用
nested_struct.a.b.c
以下是Phrogz的nice代码重构版本的要点,其中包括递归: