2011-02-06 1 views
3

J'ai un code Ruby comme ci-dessous: la version Ruby: 1.8.7Impossible d'accéder au champ `id` de OpenStruct exemple

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 

quelqu'un peut me aider sur la façon d'obtenir la valeur du champ id pour 123?

+0

Je ne reçois pas cet avertissement même avec 'ruby -w' sous 1.9.2; Quelle est la saveur et la version de Ruby? – Phrogz

+0

@Phrogz 1.8.7, ajouté la version infor à la question, merci pour votre rappel. – ywenbo

Répondre

2

Cela ressemble à un bug/une limitation de OpenStruct sous 1.8.7 où il n'y a pas d'objet BlankSlate, causé par une implémentation qui utilise method_missing pour décider si c'est une propriété spéciale ou non.

Voici une classe personnalisée similaire à OpenStruct qui fait ce que vous demandez sous 1.8.7; N'hésitez pas à développer et à rendre plus riche en fonctionnalités.

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

cool, merci beaucoup. – ywenbo

+0

De rien; notez qu'une différence majeure dans le code que j'ai fourni par rapport à OpenStruct est que vous ne pouvez pas demander un champ que vous n'avez pas défini vous-même; vous pouvez ajouter cette fonctionnalité via 'method_missing' si vous le souhaitez. Puisque cette classe définit des méthodes, je recommanderais plutôt d'utiliser 'respond_to?' Pour décider si une instance a ou non une certaine propriété à la place, cependant. Ou, alternativement, 'p hash.catz if hash.instance_variables.include? (: @catz)' – Phrogz

+0

l'a obtenu, merci. – ywenbo

4

répond à cette question dans ce blog post avec cette simple ligne de code

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

vous pouvez maintenant définir: id sur un OpenStruct et pas Ignore-vous et appelez: object_id avec un avertissement

Questions connexes