sách gpt4 ăn đã đi

Ruby Marshal.load 不保持排序集的顺序

In lại 作者:数据小太阳 更新时间:2023-10-29 07:55:03 26 4
mua khóa gpt4 giày nike

我正在使用 Marshal.dump 将 SortedSet 对象保存在文件中。集合中的元素也是对象(包括 Comparable 并实现 <=> 方法)。

稍后在使用 Marshal.load 恢复该对象时,从文件加载的 SortedSet 未排序...

知道为什么或如何解决它吗?

这是一个重现问题的简化示例:

require 'set'
class Foo
include Comparable

attr_accessor :num

def initialize(num)
@num = num
kết thúc

def <=>(other)
num <=> other.num
kết thúc
kết thúc

f1 = Foo.new(1)
f2 = Foo.new(2)
f3 = Foo.new(3)

s = SortedSet.new([f2, f1, f3])

File.open('set_test.dump', 'wb') { |f| Marshal.dump(s, f) }

然后,从我使用的文件加载对象 -

File.open('set_test.dump', 'rb') { |f| ls = Marshal.load(f) }

** 我正在使用 Rails 3.2.3 和 Ruby 2.1.8

** 从文件加载转储时 - 在新的/单独的 rails 控制台中执行(并且不要忘记复制粘贴 Foo 类的定义:-))

câu trả lời hay nhất

重现错误

我可以在我尝试过的每个 Ruby 上重现这种行为。

# write_sorted_set.rb
require 'set'
class Foo
include Comparable

attr_accessor :num

def initialize(num)
@num = num
kết thúc

def <=>(other)
num <=> other.num
kết thúc
kết thúc

f1 = Foo.new(1)
f2 = Foo.new(2)
f3 = Foo.new(3)

s = SortedSet.new([f2, f1, f3])
File.open('set_test.dump', 'wb') { |f| Marshal.dump(s, f) }
p s.to_a

# load_sorted_set.rb
require 'set'
class Foo
include Comparable

attr_accessor :num

def initialize(num)
@num = num
kết thúc

def <=>(other)
num <=> other.num
kết thúc
kết thúc

ls = Marshal.load(File.binread('set_test.dump'))
p ls.to_a

启动时

ruby write_sorted_set.rb && ruby load_sorted_set.rb

đầu ra

[#, #, #]
[#, #, #]

Tại sao?

未使用 Comparable

使用这个定义:

class Foo
attr_accessor :num
def initialize(num)
@num = num
kết thúc
kết thúc

hiện hữu load_sorted_set.rb 中应该引发异常(Foo 与 Foo 的比较失败(ArgumentError)),但它没有。看起来 SortedSet 没有被 Marshal.load 正确初始化

lib/set.rb

查看 sourcecodeSortedSet :

  module_eval {
# a hack to shut up warning
alias old_init initialize
}

      module_eval {
# a hack to shut up warning
remove_method :old_init
}

@@setup = true
kết thúc
kết thúc

def initialize(*args, &block) # :nodoc:
SortedSet.setup
initialize(*args, &block)
kết thúc
kết thúc

看起来 SortedSet 已被修补以确保 SortedSet.setup
在任何 SortedSet 初始化之前执行。

Marshal.load 似乎不知道这件事。

giải pháp

SortedSet.setup

你可以调用

SortedSet.setup

hiện hữu require 'set' 之后和 Marshal.load 之前

SortedSet.new

您可以强制 SortedSet 初始化:

ls = SortedSet.new(Marshal.load(File.binread('set_test.dump')))

关于Ruby Marshal.load 不保持排序集的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41815930/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress