當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Ruby Marshal模塊用法及代碼示例

本文簡要介紹ruby語言中 Marshal模塊 的用法。

編組庫將 Ruby 對象的集合轉換為字節流,允許將它們存儲在當前活動腳本之外。隨後可以讀取該數據並重構原始對象。

封送數據具有與對象信息一起存儲的主要和次要版本號。在正常使用中,marshaling 隻能加載使用相同的主要版本號和相等或更低的次要版本號寫入的數據。如果設置了 Ruby 的 “verbose” 標誌(通常使用 -d、-v、-w 或 -verbose),則主次編號必須完全匹配。 Marshal 版本控製與 Ruby 的版本號無關。您可以通過讀取封送數據的前兩個字節來提取版本。

str = Marshal.dump("thing")
RUBY_VERSION   #=> "1.9.0"
str[0].ord     #=> 4
str[1].ord     #=> 8

某些對象無法轉儲:如果要轉儲的對象包括綁定、過程或方法對象、類的實例 IO 或單例對象,則會引發 TypeError

如果您的類有特殊的序列化需求(例如,如果您想以某種特定格式進行序列化),或者如果它包含無法序列化的對象,您可以實現自己的序列化策略。

有兩種方法可以做到這一點,您的對象可以定義marshal_dump 和marshal_load 或_dump 和_load。 marshal_dump 將優先於 _dump 如果兩者都被定義。 marshal_dump 可能會導致較小的 Marshal 字符串。

安全注意事項

按照設計, Marshal.load 可以反序列化幾乎任何加載到 Ruby 進程中的類。在許多情況下,如果 Marshal 數據是從不受信任的源加載的,這可能會導致遠程代碼執行。

因此, Marshal.load 不適合作為通用序列化格式,您永遠不應解組用戶提供的輸入或其他不受信任的數據。

如果您需要反序列化不受信任的數據,請使用 JSON 或其他隻能加載簡單 ‘primitive’ 類型的序列化格式,例如 String Array Hash 等。切勿允許用戶輸入指定要反序列化的任意類型。

marshal_dump 和 marshal_load

轉儲對象時,將調用方法marshal_dump。 marshal_dump 必須返回包含marshal_load 重構對象所需信息的結果。結果可以是任何對象。

加載使用marshal_dump 轉儲的對象時,首先分配對象,然後調用marshal_load 並使用marshal_dump 的結果。 marshal_load 必須根據結果中的信息重新創建對象。

例子:

class MyObj
  def initialize name, version, data
    @name    = name
    @version = version
    @data    = data
  end

  def marshal_dump
    [@name, @version]
  end

  def marshal_load array
    @name, @version = array
  end
end

_dump 和 _load

當您需要分配要自己恢複的對象時,請使用 _dump 和 _load。

轉儲對象時,實例方法 _dump 使用 Integer 調用,該 Integer 指示要轉儲的對象的最大深度(值 -1 表示您應該禁用深度檢查)。 _dump 必須返回一個 String ,其中包含重構對象所需的信息。

類方法 _load 應該采用 String 並使用它返回同一類的對象。

例子:

class MyObj
  def initialize name, version, data
    @name    = name
    @version = version
    @data    = data
  end

  def _dump level
    [@name, @version].join ':'
  end

  def self._load args
    new(*args.split(':'))
  end
end

由於 Marshal.dump 輸出一個字符串,您可以讓 _dump 返回一個 Marshal 字符串,它是複雜對象的 _load 中的 Marshal.loaded。

相關用法


注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Marshal模塊。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。