开发者

Cannot access `id` field of OpenStruct instance

开发者 https://www.devze.com 2023-02-08 15:28 出处:网络
I have some开发者_开发百科 code in Ruby like below: Ruby version: 1.8.7 hash = OpenStruct.new(:id=>123, :name=>\'wenbo\')

I have some开发者_开发百科 code in Ruby like below: Ruby version: 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

Can someone help me on how to get the id field value for 123?


This question is answered in this blog post with this simple line of code

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

Now you can set :id on an OpenStruct and not have it ignore you and call :object_id with a warning


Looks like a bug/limitation of OpenStruct under 1.8.7 where there isn't a BlankSlate object, caused by an implementation that uses method_missing to decide if it's a special property or not.

Here's a custom class similar to OpenStruct that does what you ask for under 1.8.7; feel free to expand upon it and make it more feature rich.

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
0

精彩评论

暂无评论...
验证码 换一张
取 消