2015-02-04 13 views
6

Próbuję serializować prostą strukturę do JSON, który działa dobrze, ale nie mogę go uzyskać, aby utworzyć wystąpienie tej struktury z JSON. Oto, jak próbuję to zrobić.Ruby serializować struct z JSON

require 'rubygems' 
require 'json' 

Person = Struct.new(:name, :age) 

json = Person.new('Adam', 19).to_json 
puts json 

me = JSON.load(json) 
puts me.name 

I pojawia się następujący komunikat:

"#<struct Person name=\"Adam\", age=19>" 
/usr/lib/ruby/1.9.1/json/common.rb:148:in `parse': 746: unexpected token at '"#<struct Person name=\"Adam\", age=19>"' (JSON::ParserError) 
    from /usr/lib/ruby/1.9.1/json/common.rb:148:in `parse' 
    from /usr/lib/ruby/1.9.1/json/common.rb:309:in `load' 
    from why.rb:9:in `<main>' 

Odpowiedz

10

w tym przypadku person.to_json nie robi, czego oczekujesz.

Kiedy require 'json' biblioteka JSON wstawia #to_json metoda na Object że jest awaryjna, jeśli nie ma wyspecjalizowaną #to_json metoda przewidziana gdzie indziej. This inserted method jest w zasadzie taki sam jak wywołanie #to_s#to_json na obiekcie.

W przypadku Twojej klasy Person tutaj #to_s wyprowadza standard Object#to_s, która domyślnie nie umożliwia analizowania ciągów przez bibliotekę JSON.

Jednak Structma zapewnić #to_h metody, które można wykorzystać do przekonwertować struct do Hash i Hash jest (po wymagające bibliotekę JSON) wiedzą, jak generować wyjście parsowalnym JSON.

Więc po prostu zmienia:

json = Person.new('Adam', 19).to_json 
puts json 

do:

person = Person.new('Adam', 19) 
puts person.to_h.to_json 

zrobi to, czego oczekują.

(na marginesie, chciałbym polecić rzeczywiście wykonawczych #to_json na klasie Person bezpośrednio dzwoniąc #to_h#to_json narusza Law of Demeter).

+1

Dzięki które pracowały doskonale. Chciałbym zauważyć, że dla każdego, kto przeczyta to w przyszłości, metoda to_h została dodana w Ruby 2.0, więc jeśli używasz wersji 1.9.3, tak jak ja, będziesz musiał dokonać aktualizacji. –

Powiązane problemy