75 votes

Objets Ruby et sérialisation JSON (sans Rails)

J'essaie de comprendre le paysage de la sérialisation JSON en Ruby. Je suis nouveau en Ruby.

Existe-t-il de bonnes options de sérialisation JSON si vous ne travaillez pas avec Rails ?

C'est là que semble aller cette réponse (à Rails) Comment convertir un objet Ruby en JSON ?

La gemme json semble donner l'impression que vous devez écrire votre propre méthode to_json. Je n'ai pas réussi à faire fonctionner to_json avec des tableaux et des hachages (la documentation indique qu'il fonctionne avec ceux-ci). Y a-t-il une raison pour laquelle la gemme json ne reflète pas simplement l'objet et utilise une stratégie de sérialisation par défaut ? N'est-ce pas ainsi que to_yaml fonctionne (je suppose que c'est le cas) ?

116voto

david4dev Points 2578

Pour que la bibliothèque JSON soit disponible, il se peut que vous deviez installer libjson-ruby à partir de votre gestionnaire de paquets.

Pour utiliser la bibliothèque 'json' :

require 'json'

Pour convertir un objet en JSON (ces 3 façons sont équivalentes) :

JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string

Pour convertir du texte JSON en objet (ces 2 façons sont équivalentes) :

JSON.load string #returns an object
JSON.parse string #returns an object

Ce sera un peu plus difficile pour les objets de vos propres classes. Pour la classe suivante, to_json produira quelque chose comme "\"#<A:0xb76e5728>\"" .

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

Ce n'est probablement pas souhaitable. Pour sérialiser efficacement votre objet en JSON, vous devez créer votre propre méthode to_json. Pour aller de pair avec cela, une méthode de classe from_json serait utile. Vous pourriez étendre votre classe de la manière suivante :

class A
    def to_json
        {'a' => @a, 'b' => @b}.to_json
    end
    def self.from_json string
        data = JSON.load string
        self.new data['a'], data['b']
    end
end

Vous pouvez automatiser cette opération en héritant d'une classe "JSONable" :

class JSONable
    def to_json
        hash = {}
        self.instance_variables.each do |var|
            hash[var] = self.instance_variable_get var
        end
        hash.to_json
    end
    def from_json! string
        JSON.load(string).each do |var, val|
            self.instance_variable_set var, val
        end
    end
end

Vous pouvez alors utiliser object.to_json pour sérialiser en JSON et object.from_json! string pour copier l'état sauvegardé sous forme de chaîne JSON dans l'objet.

12voto

Jimothy Points 1062

Vérifiez Oj . Il y a des problèmes lorsqu'il s'agit de convertir un vieil objet en JSON, mais Oj peut le faire.

require 'oj'

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

a = A.new
puts Oj::dump a, :indent => 2

Ces sorties :

{
  "^o":"A",
  "a":[
    1,
    2,
    3
  ],
 "b":"hello"
}

Notez que ^o est utilisé pour désigner la classe de l'objet.

8voto

Greg Campbell Points 10321

Si les performances de rendu sont cruciales, vous pouvez également vous intéresser à yajl-ruby qui est une liaison avec le C yajl bibliothèque. L'API de sérialisation pour celle-ci ressemble à :

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"

7voto

the Tin Man Points 69148

Quelle version de Ruby utilisez-vous ? ruby -v vous le dira.

Si c'est 1.9.2, JSON est inclus dans la bibliothèque standard .

Si vous êtes sur 1.8.quelque chose alors faites gem install json et il s'installera. Ensuite, dans votre code, faites :

require 'rubygems'
require 'json'

Ensuite, ajoutez to_json à un objet et vous êtes prêt à partir :

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"

4voto

Reactormonk Points 7990
require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X