我无法管理Marshal.load
哈希子类的Marshal.dump
ed实例:
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:\x18MarshalDumpableHash@\x00"
p Marshal.load(Marshal.dump(MarshalDumpableHash.new(h))) #=> {} WHY?
我觉得奇怪的是,p self
方法中的marshal_dump
打印{:asd=>"ciao"}
,而marshal_load
方法中的{}
打印{{1}}
答案 0 :(得分:2)
返回marshal_dump
的方法self
不是使用marshal_dump
和marshal_load
的用例,因为内置转储和加载会这样做。因此,如果您只想编组self
,则无需编写任何自定义marshal_dump
或marshal_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_dump
和marshal_load
,生成的编组字符串将为:
"\004\bIC:\017Subclassed{\006:\bfoo:\bbar\006:\022@surplus_info\"\bfoo"
哪个有剩余信息。使用marshal加载和转储,您将能够减少编组字符串:
"\004\bIU:\017Subclassed{\006:\bfoo:\bbar\000"
这是这些方法的目的。此外,ruby doc州:
marshal_dump可能会导致Marshal字符串变小。
此外,有关使用marshal_dump
转储对象时,将调用方法marshal_dump。 marshal_dump必须返回包含marshal_load所需信息的结果,以重建该对象。结果可以是任何对象。
它应该是“结果可以是除self
之外的任何对象”。我不知道在self
中返回marshal_dump
时行为ruby显示的是非常有意的(至少一个错误会很好),或者它是否被遗忘,因为它实际上不是一个用例。