2010-10-30 38 views
3

我正在製作acts_as_taggable_on插件,但有些東西我真的不明白(即使它只是一個非常簡單的代碼行)。hash.delete_if {| key,value | true}不會刪除...爲什麼?

 
puts "before: " + cache.inspect 
# cache.delete_if { |key, value| key.id == owner.id && key.class == owner.class } # original code line 
cache.delete_if { |key, value| true } # my test code 
puts "after: " + cache.inspect 

# output
before: {#<TaggableUser id: 1, name: nil>=>["dog"]}
after: {# TaggableUser id: 1, name: nil>=>["dog"]}

我的問題是,cache.delete_if不會刪除任何東西,即使它始終計算爲真。我只是不明白爲什麼......而且真的嘗試了很多。這只是緩存哈希的問題。但我真的無法找到有關特定散列的任何特殊內容。

緩存在該方法創建:

 
def cached_owned_tag_list_on(context) 
    variable_name = "@owned_#{context}_list" 
    cache = instance_variable_get(variable_name) || instance_variable_set(variable_name, {}) 
end 

完整的代碼在這裏可以查看(見行60):http://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb#L60

一個步驟進一步

當我做一個rehash之前它的工作原理是delete_if。什麼可以在任何刪除操作之前以「重新哈希」的方式「破壞」哈希?

回答

4

rehash文件:

call-seq: 
    hsh.rehash -> hsh 

Rebuilds the hash based on the current hash values for each key. If 
values of key objects have changed since they were inserted, this 
method will reindex <i>hsh</i>. 

所以你的鑰匙(這是普通的ActiveRecord實例),有自己的哈希值從創建它們的時間而改變。看着AR的來源:

# File activerecord/lib/active_record/base.rb, line 1613 
1613:  def hash 
1614:   id.hash 
1615:  end 

所以,他們的id已被改變。爲什麼會發生?那麼,顯而易見的原因是該對象被創建,然後放入哈希,然後保存(它分配了一個id並更改了哈希)。

此外,這有另一個壞的結果:由於所有這些新創建的對象的散列是nil,如果有多個未保存的對象添加到散列,它們將佔用相同的插槽,並嘗試索引與其他一些未保存的對象的散列將返回廢話。

+0

TIL不會散列AR模型。非常可愛的答案。 – 2013-06-18 04:34:05

2

您確定cacheHash?你描述的行爲是不正常的。

$ ruby -v 
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0] 

>> h = {:a => 1, :b => 2} 
=> {:b=>2, :a=>1} 
>> h 
=> {:b=>2, :a=>1} 
>> h.delete_if {|k,v| v == 2} 
=> {:a=>1} 
>> h 
=> {:a=>1} 

>> h = {:a => 1, :b => 2} 
=> {:b=>2, :a=>1} 
>> h.delete_if {|k,v| true} 
=> {} 
>> h 
=> {} 
+0

cache.class.to_s告訴我這是一個哈希。這真的很奇怪。 – Zardoz 2010-10-30 01:42:41

+0

嘗試cache.class.ancestors,它有什麼混合? Rails有時會改變一些事情,例如,它的哈希值對字符串/符號訪問無關緊要,ActiveSupport帶有一個完整的OrderedHash類。 – 2010-11-01 08:07:49

0

也許這是一個acts_as_taggable_on的錯誤,您可以填寫一個錯誤報告。

+0

是的,也許...也有可能...但這就是我想要找出並解決的;-) – Zardoz 2010-11-01 00:03:06

相關問題