这是Ruby中一组数组的预期行为吗?

这是Ruby中一组数组的预期行为吗?,ruby,set,concat,Ruby,Set,Concat,我们在Ruby 1.8.7中做了一些工作,需要遍历和划分一个无向图,这在生产中异常失败。当我将失败的代码细化到最简单的组件时,我得到了一个奇怪的失败测试: it 'should be able to clear a ruby set of arrays' do a = ["2", "b", "d"] b = ["1", "a", "c", "e", "f"] set = Set.new([a, b]) a.concat(b) p "before clear: #{set.i

我们在Ruby 1.8.7中做了一些工作,需要遍历和划分一个无向图,这在生产中异常失败。当我将失败的代码细化到最简单的组件时,我得到了一个奇怪的失败测试:

it 'should be able to clear a ruby set of arrays' do
  a = ["2", "b", "d"]
  b = ["1", "a", "c", "e", "f"]
  set = Set.new([a, b])
  a.concat(b)

  p "before clear: #{set.inspect}"
  set.clear
  p "after clear: #{set.inspect}"
  set.size.should == 0
end
此输出导致测试失败:

"before clear: #<Set: {[\"1\", \"a\", \"c\", \"e\", \"f\"], [\"2\", \"b\", \"d\", \"1\", \"a\", \"c\", \"e\", \"f\"]}>"
"after clear: #<Set: {[\"2\", \"b\", \"d\", \"1\", \"a\", \"c\", \"e\", \"f\"]}>"

expected: 0
     got: 1 (using ==)
“清除之前:#” “清除后:#” 预期:0 获取:1(使用==)
试图从集合中删除的行为也很奇怪。我猜Ruby在concat()下更改数组中键的散列值时遇到了问题,但我肯定仍然能够清除该集。对吗?

有一个解决方法,如果在修改关键点后复制该集,新集将具有更新的关键点并正确清除。因此,设置
set=set.dup
将解决这个问题。

实际上,.dup方法是我的第一个解决方法,并按照宣传的那样做了

我最后添加了以下要设置的猴子补丁:

class Set
  def rehash
    @hash.rehash
  end
end
这允许我在任何更改哈希值的操作后重新刷新集合的键


这似乎在Ruby 1.9中都得到了修复。

Ruby 1.9.3p125和您的一样没有问题。我刚刚找到了这个,它回答了有关删除的问题。但这并不是clear失败的原因。set.clear使用hash.clear清除其内部哈希。Hash.clear使用Hash.for_each删除每个哈希项。所以,如果有一个bug影响删除,它将影响清除。遗憾的是,这在JRuby中不起作用。对于JRuby,您必须在执行任何需要最新密钥的操作之前复制集合。