【问题标题】:Round-trip JSON serialization in RubyRuby 中的往返 JSON 序列化
【发布时间】:2015-01-05 19:10:30
【问题描述】:

假设我有一个简单的类

class Person
  attr_accessor :name
  def say
    puts name
  end
end

有没有办法将它序列化为 JSON 并返回并获取同一类的实例? 例如,我想要一个类似的代码

p = Person.new
p.name = 'bob'
json = JSON.serialize p
# json should be smth. containing { 'name' : 'bob' } 
# and maybe some additional information required for later deserialization
p2 = JSON.deserialize
p2.say
# should output 'bob'

我尝试了 as_json(我猜来自 ActiveSupport),但结果是 {'name': 'bob'} 并且显然类型信息丢失了,反序列化后我只有一个哈希,而不是 Person 实例。

【问题讨论】:

  • 我不明白你的问题。你到底想做什么?
  • @gmaliar,引用的问题涵盖二进制序列化,而不是 JSON
  • 这是唯一的方法。

标签: ruby json serialization deserialization


【解决方案1】:

Ruby 的 JSON 库支持 Marshal 接口。简短的回答:你需要在你的类中定义 #to_json 和 self#json_create。

诀窍是您需要将要往返返回的类的名称存储在 json 本身中;执行此操作的默认位置是键 json_class 的值,可能没有理由更改它。

这是一个非常简单的例子:

require 'json'

class A
  attr_accessor :a,:b

  def initialize(a,b)
    @a = a
    @b = b
  end

  def to_json(*a)
    {
      "json_class"   => self.class.name,
      "data"         => {:a => @a, :b=>@b}
    }.to_json(*a)
  end

  def self.json_create(h)
      self.new(h["data"]["a"], h["data"]["b"])
  end

end

然后你可以用JSON.generate 和JSON.load 来回它。请注意JSON.parse 将不起作用;它只会给您返回预期的哈希值。

[29] pry(main)> x = A.new(1,2)
=> #<A:0x007fbda457efe0 @a=1, @b=2>
[30] pry(main)> y = A.new(3,4)
=> #<A:0x007fbda456ea78 @a=3, @b=4>
[31] pry(main)> str = JSON.generate(x)
=> "{\"json_class\":\"A\",\"data\":{\"a\":1,\"b\":2}}"
[32] pry(main)> z = JSON.load(str)
=> #<A:0x007fbda43fc050 @a=1, @b=2>
[33] pry(main)> arr = [x,y,z]
=> [#<A:0x007fbda457efe0 @a=1, @b=2>, #<A:0x007fbda456ea78 @a=3, @b=4>, #<A:0x007fbda43fc050 @a=1, @b=2>]
[34] pry(main)> str = JSON.generate(arr)
=> "[{\"json_class\":\"A\",\"data\":{\"a\":1,\"b\":2}},{\"json_class\":\"A\",\"data\":{\"a\":3,\"b\":4}},{\"json_class\":\"A\",\"data\":{\"a\":1,\"b\":2}}]"
[35] pry(main)> arr2 = JSON.load(str)
=> [#<A:0x007fbda4120a48 @a=1, @b=2>, #<A:0x007fbda4120700 @a=3, @b=4>, #<A:0x007fbda4120340 @a=1, @b=2>]  

【讨论】:

    猜你喜欢
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2012-06-09
    • 2014-03-08
    • 1970-01-01
    • 2014-04-18
    • 2011-07-05
    相关资源
    最近更新 更多