这是一段代码
myHash = Hash.new {|h, k| h[k] = []}
myHash[5] << 1 # example operation
Marshal.dump(myHash)
当我尝试使用任意键操作它时,我经常使用它,而且我不想明确地写这样的东西
myHash = Hash.new
myHash[5] ||= [] # initialize it first, if needed
myHash[5] << 1 # example operation
Marshal.dump(myHash)
虽然它只是一行代码差异,但对我来说使用块版本看起来更清晰。
但是,在序列化过程中会出现问题
in `dump: can't dump hash with default proc (TypeError)
有没有办法在继续使用构造函数的块形式的同时序列化它?或者,在尝试操作哈希值之前,我是否必须坚持显式检查和初始化任何值?
我会说不,因为没有真正的方法让ruby确定如果在没有传入原始proc的情况下丢失密钥时散列应该如何自动生成值。
答案 0 :(得分:1)
在转储哈希值之前删除默认行为。
myHash = Hash.new {|h, k| h[k] = []}
myHash[5] << 1
myHash.default = nil
Marshal.dump(myHash)
或者,因为您似乎对保留垂直空间感兴趣:
myHash = Hash.new {|h, k| h[k] = []}
myHash[5] << 1
Marshal.dump(myHash.tap {|h| h.default = nil })
但是,这会永久更改哈希值,使其不再具有默认值。如果这困扰你,但暂时复制你的哈希的顶级不是,请抛出.dup
:
Marshal.dump(myHash.dup.tap {|h| h.default = nil })
现在原始哈希的默认行为保持不变。
答案 1 :(得分:1)
来自http://www.ruby-doc.org/core-2.1.0/Marshal.html第3段:
无法转储某些对象:如果要转储的对象包括绑定,过程或方法对象,类IO实例或单例对象,则会引发TypeError。
这是一个简单的例子:
class X
def initialize a
@a = a
end
end
Marshal.dump(X.new(1))
=&GT; “\ X04 \博:\ x06X \ X06:\一个@人工智能\ X06”
proc = Proc.new {1}
=&GT; PROC:0x007ff992716428
Marshal.dump(X.new(PROC))
TypeError:没有为类Proc
定义_dump_data使用块创建哈希时,哈希的default_proc属性为Proc:
h = Hash.new {1}
=&GT; {}
h.default_proc
=&GT; #Proc:0x007ff99506ce30 @
创建没有块的哈希时,它没有default_proc:
h = Hash.new
=&GT; {}
h.default_proc
=&GT;零