2012-06-12 20 views
4

我們在Ruby 1.8.7中做了一些工作,它需要遍歷和分區一個無向圖,這在生產中一直都很奇怪。當我提煉失敗碼至其最起碼的組成部分,我得到這個奇怪的失敗的測試:這是Ruby中一組數組的預期行爲嗎?

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 ==) 

試圖從集中刪除也表現在陌生方法。我在猜測Ruby正在掛在concat()下更改數組中鍵的哈希值,但我當然應該仍然可以清除Set。對?

+1

像你的紅寶石1.9.3p125沒有問題。 – megas

+0

我剛剛發現這個,它回答了關於刪除的問題。但不是爲什麼明確失敗。 http://stackoverflow.com/questions/10361400/deleting-a-modified-object-from-a-set-in-a-no-op – Nello

+0

set.clear使用hash.clear來清除它的內部散列。 Hash.clear使用hash.for_each刪除每個哈希項。所以如果有一個影響刪除的錯誤,它會影響清晰。 – philosodad

回答

1

對此有一種解決方法,如果在修改密鑰後複製集合,新集合將具有更新的密鑰並正確清除。所以設置set = set.dup將解決這個問題。

1

.dup方法確實是我的第一個解決方法,並且按照廣告方式進行。

我最終加入以下猴子補丁設置:

class Set 
    def rehash 
    @hash.rehash 
    end 
end 

,讓我改變自己的哈希值進行任何操作後,老調重彈集合的鑰匙。

這似乎都在Ruby 1.9中解決。

+0

不幸的是,這在JRuby中不起作用。對於JRuby,在執行任何需要最新密鑰的操作之前,您一直在複製Set。 – Nello

相關問題