2011-10-27 6 views
6

私はシリアル化と検証について前の質問をしました。誰かが私のオブジェクトにto_jsonメソッドでシリアル化する方法を伝えることを可能にするJSONの宝石を使って言いましたが、Rubyは複雑なものがたくさんあるようですが、実際にはシンプルなものはかなり複雑です。それらの事の一つ。オブジェクトをJSON、XML、YAMLにシリアル化しますか?

私はクリーンなオブジェクトを持つ方法があるかどうかを知りたい:

class CleanClass 
    attr_accessor :variable1 
    attr_accessor :variable2 
    attr_accessor :variable3 
end 

cleanObject = CleanClass.new 

理想的には、私は汚いモデルにしたくない、私はちょうど何かにそれを渡したいと出力タイプが何であるべきかを伝え、それがその魔法を働かせるようにしてください。それをバックに変換することができ、その後、私は何かのオブジェクトを渡したい、との文字列が出力されます

jsonOutput = MagicSerializer::Json.Serialize(cleanObject) 
xmlOutput = MagicSerializer::Xml.Serialize(cleanObject) 
yamlOutput = MagicSerializer::Yaml.Serialize(cleanObject) 

revertedJsonObject = MagicSerializer::Json.Unserialize(jsonOutput) 
revertedXmlObject = MagicSerializer::Xml.Unserialize(xmlOutput) 
revertedYamlObject = MagicSerializer::Yaml.Unserialize(yamlOutput) 

例は次のようなものになるだろう。

ActiveModelにはシリアライズ機能がありますが、これを行うにはクラスをダーティにする必要があり、できるだけモデルを変更したくありません。 ActiveSupportはJSONの基準を満たしているようですが、私はそれを呼び出すだけで、オブジェクトを取得してJSONを吐き出すことになりますが、他のタイプをサポートしたいと思います。

これ以上の情報はありません。あなたはコアタイプ(周りに独自のクラスをラップする必要がありますJSONのためにJSONとYAMLについては

+0

'JSON.dump(オブジェクト)'と 'JSON。parse(string) ' – Kris

答えて

11

Rubyにはバイナリとyamlへの自動逐次化/逆シリアル化が組み込まれています。

YAML:

require 'yaml' 
serialized = CleanClass.new.to_yaml 
object = YAML.load(serialized) 

元帥:

serialized = Marshal.dump(CleanClass.new) 
object = Marshal.load(serialized) 
+0

私はこれらを見ましたが、Jsonは現在私のために最も重要です。ヤムだから私は、単純化されたインターフェースからすべてを行う宝石や図書館があることを期待していました。 – Grofit

+1

JSON形式は、ルビオブジェクト全体の状態を取得するにはあまりにも制限されています。プリミティブがあるだけなので、インスタンス変数の型情報を含むようにJSONをカスタマイズする必要があります。さらに、目的がシリアライゼーションであるため、オブジェクトを別の場所に読み戻すことができる場合は、おそらくAPIに準拠する必要があります。 – Ewout

+0

上記のDaveへの返答で私が言ったように、なぜあなたがRubyにこれらのクラスを直列化するかを伝える必要があるのか​​分かりません(仮定を使用して)上記)。彼らが本当に必要とするのは、オブジェクトの各インスタンスを通過する再帰的なメソッドです。オブジェクトが別のオブジェクトに到達し、さらにツリーに落ちると、すべてのオブジェクトが最後に単純な型のモデルとして終わることが確かです。シリアライゼーションロジック自体を入力する必要があるのは、attr_accessor:Surnameを姓やそれに類するものにシリアル化する必要がある場合だけです。 – Grofit

1

彼らは唯一の(それぞれまたはYAML.loadfrom_jsonto_yamlto_jsonメソッドのラッパーになりますので、それは、とても簡単そうです

またはto_jsonを実装する他の型)最初にto_hashメソッドを実装し、それをjsonに変換することができます。

XMLは階層的な側面のためにはるかに複雑です。 を標準化する必要がありますが、実際には私はあなたの説明から基本的なto_...メソッドの何が問題なのか分かりません。これは実際にRubyで使用する規約です。モデルの汚染に懸念がある場合は、これらのメソッドをモジュールに入れ、モジュールをクラスに含めることができます。

module Foo 
    def to_serialized_type 
    ... 
    end 
end 
class CleanClass 
    include Foo 
end 
+0

自分のクラスのインスタンスでto_xxxxを使用しようとするときに、クラス内にto_xxxxメソッドを書いて、どのようにシリアライズするか(現在読んでいるものから出てくるか、 {something:blah}の代わりに#<9135f3>のように)。それは直列化に関する懸念を持ってモデルを汚染したくないという問題です。 – Grofit

+0

それはあなたがルビーで普通に働く方法のようなものなので、それは汚染されていません:機能的ではなくオブジェクト上で直接 – robustus

1

汚れたあなたの魔法のシ​​リアル化方法あなたのためのオブジェクトを持っています。 emdirteringはオブジェクト単位で発生する可能性があります。

あなたのクラスレベルで汚いです。

いずれにしても、メインラインコードでは表示されません。

+0

もっと詳しく教えてもらえますか?宣言の後にクラスに追加することができます。しかし、たとえ私がそのクラスの外にいくつかのコードを書いて、直列化する方法を教えても、私のプロジェクト内で保守しなければならないコードが増え、クラスの種類ごとに記述する必要があります。つまりPersonクラスにファーストネームと姓がある場合、ビジネスクラスには名前とアドレスフィールドがあり、それに対応するために2つの別々のシリアライゼーションロジックを書く必要があり、複雑なオブジェクトグラフではメンテナンスができなくなります。 – Grofit

+0

既存のシリアライゼーションコードには、少なくとも単純なプロパティの場合、オブジェクトを書き出す方法が示されていないため、オブジェクトに問い合わせます。複雑な直列化が必要な場合は、how/somewhere /にそれを伝える必要があります。あなたは基本的に2つのことを求めています:私は自分のクラスがどのようにシリアライズされたかを完全にコントロールしたいが、私のクラスではその情報を望んでいない。このようには動作しません。直列化/どこかでどのように定義されるかを定義する必要があります。 –

+0

私はクラスをシリアル化する方法を完全に制御するよう求めているわけではありません。私はちょうどそれをシリアル化したい、次の前提は、ユーザーの部分に何の努力なしに自動シリアル化されている任意のクラスを作ることができます。公開されているフィールド/変数のみがシリアル化され、キー値のペアとして使用されます。値が別のクラスでない限り、すべての単純型がシリアル化されるまで再帰を使用してツリーを下ります。私は彼らが公平な仮定であると思うが(私はルビーをよく知っていないが)、アクセスするには十分に簡単でなければならない。 – Grofit

関連する問題