1

以下代码生成一个TypeError (can't modify freeze object)。但是我们所做的只是复制缓存的项目。有谁知道为什么?我们在 Rails 3.0.6 和 Ruby 1.8.7 上。谢谢!

我们还尝试使用克隆然后解冻生成的对象,但这也产生了相同的异常。

pack没有在其他任何地方定义。

    cached_pack = Rails.cache.fetch( 'packs/' + pack_id, {:expires_in => 10.days} ) do
        Rails.logger.info '+++ Cache miss: '
        Pack.find pack_id
    end         

    pack = cached_pack.dup
4

2 回答 2

0

TLDNR版本:使用clone,而不是dup

clone和之间有两个主要区别dup

  • dup不克隆单例方法,而clone这样做;
  • 冻结对象的 theclone也被冻结(而dup冻结对象的 a 不是)。

这就是它在 Rails 3.1+ 中的工作方式。在您的情况下,您应该使用clone因为ActiveRecord#dup在 Rails 3.1 中引入,因此您可能会调用Kernel#dup.

UPD BTW,Rails.cache静默冻结对象,被放入缓存中(至少在 Rails < 3.2 中)。为了避免这种行为,可以将对象的副本而不是对象本身缓存:

cached_resource.cache.write( \
  key, object.dup, :expires_in => cached_resource.generate_ttl \
)
于 2013-03-01T05:32:49.250 回答
0

解决方案是升级到 Rails 3.1 或更高版本,因为那时引入了 dup。

于 2013-03-07T04:50:24.727 回答