繁体   English   中英

hash.delete_if {| key,value | true}不删除...为什么?

[英]hash.delete_if { |key, value| true } doesn't delete … why?

我正在处理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

更进一步

当我在delete_if之前进行rehash工作时。 什么可以在任何删除工作之前以重新哈希的方式“破坏”哈希?

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的哈希,如果有多个未保存的对象添加到哈希,它们都将占用相同的槽,并尝试使用一些哈希索引哈希其他未保存的对象将返回废话。

你确定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
=> {}

也许这是acts_as_taggable_on的错误,你可以填写错误报告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM