簡體   English   中英

為什么封送處理可以序列化循環引用列表而json無法序列化?

[英]Why marshaling can serialize circular referenced list and json can't?

這里有一個循環引用列表

2.1.9 :082 > a = []
 => [] 
2.1.9 :083 > a.append(a)
 => [[...]] 

當試圖轉儲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中引入這樣的構造以方便當前情況。 我可能缺少有關封送處理和序列化的更基本的知識,請啟發我。

以我的理解,它們都是將對象轉換為字符串並從字符串中獲取對象。

是。 這幾乎就是“序列化”或“封送處理”的定義。

我還可以看到json沒有任何構造可引用json的其他部分,這可能是它不支持這種操作的原因。

是的,這就是原因。

但是很難在json中引入這樣的構造以方便當前情況。

您不能在JSON中引入構造。 它是故意設計成沒有版本號的,因此永遠不能更改。

當然,這僅僅意味着我們不能添加現在 ,但也道格克羅克福德從一開始就加入了,回來時,他正在設計JSON? 當然是。 但是他沒有。 故意將JSON設計為簡單(我的粗體強調)

JSON不是文檔格式。 它不是標記語言。 它甚至不是通用的序列化格式,因為它沒有循環結構的直接表示形式 […]

例如,請參見YAML ,它是JSON的超集,它具有引用,因此可以表示周期性數據。

Marshal.dumpto_json返回一個String,但這就是它們的共同點。

to_json

to_json返回一個根據JSON 規范描述Ruby對象的String。

to_json基本上需要在每個可能的Ruby對象上進行猴子修補,並且在Array上調用時,將在每個元素上遞歸調用它:

"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"

此遞歸是獲得以下內容的原因:

ActiveSupport::JSON::Encoding::CircularReferenceError: object references itself

如果導出成功,則新的Rubinius腳本可以讀取在舊的JRuby on Rails服務器或PHP服務器上編寫的JSON字符串。

傾倒

Marshal.dump返回一個字節流,該字節流表示對象本身以及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存儲a因為它已被定義為:一個元件陣列,參照本身。

前兩個字節是主要和次要版本號。 比較具有相同版本的轉儲對象時,可以使用以下命令忽略它們:

Marshal.dump(a).bytes.drop(2)
#=> [91, 6, 64, 0]
Marshal.dump([[]]).bytes.drop(2)
#=> [91, 6, 91, 0]

由於表示形式取決於Ruby實現,因此從一個Ruby腳本轉儲到另一個Ruby腳本可能並不總是可行。

文檔

在正常使用中,封送處理只能加載使用相同主版本號和相等或更低的次版本號寫入的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM