我正在处理acts_as_taggable_on插件,但有一些我无法理解的东西(即使它只是一个非常简单的代码行)。
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不会删除任何内容,即使它总是计算为true。我根本就不明白为什么......并且真的尝试了很多。这只是缓存哈希的问题。但我真的找不到任何特别的哈希值。
使用该方法创建缓存:
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
时。什么可以在任何删除工作之前以重新散列的方式“破坏”哈希?
答案 0 :(得分: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
并更改其哈希)。
此外,这还有另一个不好的后果:由于所有新创建的对象的哈希都是nil
的哈希,如果有多个未保存的对象添加到哈希,它们都将占用相同的槽,并且尝试使用其他未保存的对象索引哈希将返回无意义。
答案 1 :(得分:2)
您确定cache
是Hash
吗?您描述的行为不正常。
$ 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
=> {}
答案 2 :(得分:0)
也许这是acts_as_taggable_on的错误,您只需填写错误报告即可。