反序列化对象的转换
一般用例是您想要对要反序列化的对象执行一些操作或转换。例如,使用一些 Ruby 2.7.1 快捷方式:
Marshal.load Marshal.dump("abc"), ->{ _1.to_s.upcase }
#=> "ABC"
这在反序列化单个对象时不会增加太多价值,但如果您正在处理批量转储的对象,则可能非常有用。我想不出一个实用的用例,你不能在反序列化 之后进行转换,但是 Ruby 有很多有用的工具可以在没有中间步骤的情况下处理事情。这似乎是其中之一。
可能的错误:Procs 似乎运行两次但返回一次
在上面的示例中,我将第一个位置参数强制转换为字符串,否则我会在通过 lambda 进行的两次传递中的一次获得 NoMethodError。您可以按如下方式解开正在发生的事情(但也许不是为什么):
prc = proc { |obj| pp obj }
Marshal.load Marshal.dump("abc"), prc
"abc"
true
#=> "abc"
无论出于何种原因,Proc 或 lambda 的主体都被调用了两次,但只有 返回第一次。当第二次调用在 TrueClass 上调用时引发 NoMethodError 异常时,就会出现问题,因此该调用永远不会返回值。
另一种处理方式是显式处理异常,例如:
prc = proc { |obj| obj.upcase rescue NoMethodError }
或避免在true 上调用方法:
prc = proc { |obj| obj.upcase unless obj == true }
虽然我可以解释 发生了什么 以及如何解决它,但我无法告诉你 为什么 使用类 proc 对象调用会以这种方式运行.这是 Ruby 核心团队的问题,或者是 Ruby bug tracker 的素材。