Ruby Marshal.dump 对看似相同的事物给出不同的结果

Ruby Marshal.dump gives different results for what looks like the same thing

我看到 Ruby 的 Marshal.dump 的结果略有不同,这取决于我是对某事调用 .to_s 还是输入字符。我真的不清楚这里发生了什么:

»  Marshal.dump(1.to_s)
=> "\x04\bI\"\x061\x06:\x06EF"
»  Marshal.dump('1')
=> "\x04\bI\"\x061\x06:\x06ET"
»  1.to_s == '1'
=> true

因此,尽管看起来 1.to_s == '1',但它们不会转储到相同的东西,但唯一的区别在于最后一个字节。知道为什么会发生这种情况以及如何将这两个东西转储到相同的字节序列吗?

Marshal.load("\x04\bI\"\x061\x06:\x06EF").encoding
# => #<Encoding:US-ASCII> 
Marshal.load("\x04\bI\"\x061\x06:\x06ET").encoding
# => #<Encoding:UTF-8>

默认情况下,1.to_s.encoding'1'.encoding 不同。然而,这两个字符串都在 7 位 ASCII 范围内,因此它们是可比较的,并且 '1' == 1.to_s 将能够在一些内部魔法之后为您提供结果 true。但它们不是一回事。

Marshal.dump(1.to_s.force_encoding('utf-8'))
# => "\x04\bI\"\x061\x06:\x06ET"
Marshal.dump('1')
# => "\x04\bI\"\x061\x06:\x06ET"

(假设你 运行 它在较新的 Ruby 上,并且不要弄乱源编码。)