2013-02-22 72 views
0

的子類的實例我不能設法Marshal.load的哈希的子類的Marshal.dump版實例:加載元帥元帥傾倒的哈希

class MarshalDumpableHash < Hash 

    def initialize(constructor = {}) 
    if constructor.is_a?(Hash) 
     super() 
     update(constructor) 
    else 
     super(constructor) 
    end 
    end 

    def marshal_dump 
    p self 
    self 
    end 

    def marshal_load(hash) 
    p hash 
    update(hash) 
    end 

end 


h = { asd: 'ciao' } 

p MarshalDumpableHash.new(h) #=> {:asd=>"ciao"} 
p Marshal.dump(MarshalDumpableHash.new(h)) #=> "\x04\bU:\[email protected]\x00" 

p Marshal.load(Marshal.dump(MarshalDumpableHash.new(h))) #=> {} WHY? 

這聽起來很奇怪,我的p selfmarshal_dump方法打印{:asd=>"ciao"},而一個所述marshal_load方法打印{}

回答

2

的方法marshal_dump返回self內不是使用marshal_dump和一個用例,因爲內置的傾倒和加載是這樣做的。所以如果你只想要編組self,你不必寫任何定製的marshal_dumpmarshal_load

class Subclassed < Hash 
end 

s = Subclassed.new 
s[:foo] = :bar 
Marshal.load(Marshal.dump(s)).class #=> Subclassed 

這些方法適用於當您在加載轉儲對象時不希望重新加載對象的剩餘信息時使用的用例。這是爲了節省空間。例如:

class Subclassed < Hash 

    attr_reader :surplus_info 

    def initialize(surplus_info) 
    @surplus_info = surplus_info 
    end 

    def marshal_dump 
    Hash.new.merge(self) 
    end 

    def marshal_load other 
    update(other) 
    end 
end 

沒有marshal_dumpmarshal_load,所產生的編組字符串將是:

"\004\bIC:\017Subclassed{\006:\bfoo:\bbar\006:\[email protected]_info\"\bfoo" 

其中有剩餘信息。隨着元帥負載和轉儲,你將能夠減少編組字符串:

"\004\bIU:\017Subclassed{\006:\bfoo:\bbar\000" 

這是這些方法的目的。另外,ruby doc指出:

marshal_dump可能會導致較小的元帥字符串。

此外,該文檔是有點模糊有關使用marshal_dump

當傾倒的對象marshal_dump將被調用的方法。 marshal_dump必須返回包含marshal_load重構對象所需信息的結果。結果可以是任何對象。

它應該可能被讀取「結果可以是除self之外的任何對象」。我不知道在返回selfmarshal_dump是否真的是故意的(至少有一個錯誤會很好),或者如果它被遺忘了,因爲它不是真正的用例,所以我不知道該行爲是否是紅寶石。

+0

我沒有想到在'marshal_dump'裏面返回'self'可能是個問題......謝謝 – mdesantis 2013-02-25 08:46:59