为什么封送处理可以序列化循环引用列表,而json不能?
这里我有一个循环引用列表为什么封送处理可以序列化循环引用列表,而json不能?,json,ruby,serialization,marshalling,circular-reference,Json,Ruby,Serialization,Marshalling,Circular Reference,这里我有一个循环引用列表 2.1.9 :082 > a = [] => [] 2.1.9 :083 > a.append(a) => [[...]] 当我试图将一个文件转储为json时,我得到了一个错误 a.to_json ActiveSupport::JSON::Encoding::CircularReferenceError: object references itself 但是当我试图封送它们时,我得到了一个有效的字符串 2.1.9 :085 >
2.1.9 :082 > a = []
=> []
2.1.9 :083 > a.append(a)
=> [[...]]
当我试图将一个文件转储为json时,我得到了一个错误
a.to_json
ActiveSupport::JSON::Encoding::CircularReferenceError: object references itself
但是当我试图封送它们时,我得到了一个有效的字符串
2.1.9 :085 > Marshal.dump(a)
=> "\x04\b[\x06@\x00"
我只是试图通过再次加载来确保它们正确地转储了值
b = Marshal.load("\x04\b[\x06@\x00")
=> [[...]]
下面是一些验证,以确保它们正确地将对象转储到字符串
2.1.9 :088 > a.object_id
=> 70257482733700
2.1.9 :089 > a.first.object_id
=> 70257482733700
2.1.9 :090 > b.object_id
=> 70257501553000
2.1.9 :091 > b.first.object_id
=> 70257501553000
2.1.9 :092 >
据我所知,他们都在将一个对象转换为字符串,并从字符串中取回该对象。我还可以看到json没有任何引用json其他部分的构造,这可能是它无法支持此类操作的原因。但是,在json中引入这样的构造来促进当前的情况是否有那么困难呢。关于封送和序列化,我可能遗漏了一些更基本的内容,请告诉我。Marshal.dump和to_json都返回字符串,但这就是它们的共同点
到u json
to_json根据json返回一个描述Ruby对象的字符串
to_json基本上需要在每个可能的Ruby对象上进行猴子补丁,当在数组上调用时,它会在每个元素上调用:
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"
这种递归是您得到以下结果的原因:
ActiveSupport::JSON::Encoding::CircularReferenceError: object references itself
如果导出成功,新Rubinius脚本可以读取在旧JRuby on Rails服务器或PHP服务器上编写的JSON字符串
倾倒
返回一个字节流,表示对象本身,以及Ruby如何在内部存储该对象:
Marshal.dump(a).bytes
#=> [4, 8, 91, 6, 64, 0]
Marshal.dump([[]]).bytes
#=> [4, 8, 91, 6, 91, 0]
Marshal.dump([]).bytes
#=> [4, 8, 91, 0]
因此,Marshal.dump按定义存储一个数组:一个引用自身的单元素数组
前两个字节是主版本号和次版本号。将转储对象与相同版本进行比较时,可以通过以下方式忽略它们:
Marshal.dump(a).bytes.drop(2)
#=> [91, 6, 64, 0]
Marshal.dump([[]]).bytes.drop(2)
#=> [91, 6, 91, 0]
因为表示依赖于Ruby实现,所以从一个Ruby脚本转储到另一个可能并不总是有效的
从:
在正常使用情况下,封送处理只能加载使用相同的文件写入的数据
主要版本号和相等或更低的次要版本号
Marshal.dump和to_json都返回一个字符串,但这就是它们的共同点
到u json
to_json根据json返回一个描述Ruby对象的字符串
to_json基本上需要在每个可能的Ruby对象上进行猴子补丁,当在数组上调用时,它会在每个元素上调用:
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"
这种递归是您得到以下结果的原因:
ActiveSupport::JSON::Encoding::CircularReferenceError: object references itself
如果导出成功,新Rubinius脚本可以读取在旧JRuby on Rails服务器或PHP服务器上编写的JSON字符串
倾倒
返回一个字节流,表示对象本身,以及Ruby如何在内部存储该对象:
Marshal.dump(a).bytes
#=> [4, 8, 91, 6, 64, 0]
Marshal.dump([[]]).bytes
#=> [4, 8, 91, 6, 91, 0]
Marshal.dump([]).bytes
#=> [4, 8, 91, 0]
因此,Marshal.dump按定义存储一个数组:一个引用自身的单元素数组
前两个字节是主版本号和次版本号。将转储对象与相同版本进行比较时,可以通过以下方式忽略它们:
Marshal.dump(a).bytes.drop(2)
#=> [91, 6, 64, 0]
Marshal.dump([[]]).bytes.drop(2)
#=> [91, 6, 91, 0]
因为表示依赖于Ruby实现,所以从一个Ruby脚本转储到另一个可能并不总是有效的
从:
在正常使用情况下,封送处理只能加载使用相同的文件写入的数据
主要版本号和相等或更低的次要版本号
据我所知,他们都在将一个对象转换为字符串,并从字符串中取回该对象
对。这几乎就是序列化或封送处理的定义
我还可以看到json没有任何引用json其他部分的构造,这可能是它无法支持此类操作的原因
是的,这就是原因
但是,在json中引入这样的构造来促进当前的情况是否有那么困难呢
不能在中引入构造。它被故意设计成没有版本号,所以它永远不会被改变
当然,这只意味着我们现在不能添加它,但是Doug Crockford是否可以从一开始就添加它,回到他设计JSON的时候?当然可以。但他没有:
JSON不是文档格式。它不是一种标记语言。它甚至不是一般的序列化格式,因为它没有循环结构的直接表示[…]
例如,请参见JSON的超集,它具有引用,因此可以表示循环数据
据我所知,他们都在将一个对象转换为字符串,并从字符串中取回该对象
对。这几乎就是序列化或封送处理的定义
我还可以看到json没有任何引用json其他部分的构造,这可能是它无法支持此类操作的原因
是的,这就是原因
但是,在json中引入这样的构造来促进当前的情况是否有那么困难呢
不能在中引入构造。它被故意设计成没有版本号,这样它就永远不会有b
我变了
当然,这只意味着我们现在不能添加它,但是Doug Crockford是否可以从一开始就添加它,回到他设计JSON的时候?当然可以。但他没有:
JSON不是文档格式。它不是一种标记语言。它甚至不是一般的序列化格式,因为它没有循环结构的直接表示[…]
例如,请参见JSON的超集,它具有引用,因此可以表示循环数据