2011-01-18 8 views
5

Voglio convertire un hash a un oggetto utilizzando OpenStruct che ha una proprietà id, tuttavia il risultante object#id restituisce l'id oggetto nativo, ad es.Ignora id su un oggetto ruby ​​(creato con OpenStruct)

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

Esiste comunque la possibilità di ignorare questo? Al momento la mia soluzione non è così carina.

risposta

6

OpenStruct utilizza una combinazione di define_method chiamate all'interno di un controllo unless self.respond_to?(name) e method_missing. Ciò significa che se il nome della proprietà è in conflitto con il nome di qualsiasi metodo esistente sull'oggetto, si verificherà questo problema.

tokland's risposta buona, ma un'altra alternativa è quella di indefinire il metodo id, ad es.

test.instance_eval('undef id') 

Si potrebbe anche incorporare questo nella vostra propria versione personalizzata di OpenStruct esempio

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 
+0

Suona bene, non è necessario dipende da qualsiasi variabile di istanza (@table, che può essere refactored). – tokland

1

Questa era la soluzione classica, sarei anche contento di sentire un modo migliore:

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

che ho passato a utilizzare Hashery e la BasicStruct (versione rinominata di OpenObject nella versione più recente, 1.4) come che mi permette di fare questo:

x = BasicStruct.new({:id => 666, :sub => BasicStruct.new({:foo => 'bar', :id => 777})}) 
x.id  # => 666 
x.sub.id # => 777 
x.sub.foo # => "bar" 
Problemi correlati