我有一个Letter模型。它定义了两种不同的发送方法,用于将字母作为散列发送:
class Letter < ActiveRecord::Base
SEND_METHODS = {
'Paper' => 0,
'Online' => 1
}
在某些情况下,发送方法在线不可用,因此我在控制器的新和编辑操作中将其删除:
@send_methods = Letter::SEND_METHODS
if letter.paper?
@send_methods.delete 'Online'
end
我知道,这段代码闻起来了。 (如果字母模型有一个方法,给我带有正确的条目,那就更好了。)但这不是重点。
我遇到过这段代码的奇怪行为。虽然,我将类常量 Letter :: SEND_METHODS 分配给实例变量 @send_methods ,但 @send_methods -hash有时并没有有条目 {&#39; Online&#39; =&GT; 1} ,即使 letter.paper? false 。我发现, @send_methods 有时候没有条目 {&#39; Online&#39; =&GT; 1} 在分配后直接。
我的解释是, @send_methods 是通过引用分配的,但Ruby总是按值分配...
谁能说明我的意见?
答案 0 :(得分:3)
因为您要将其删除,所以缺少密钥:
SEND_METHODS = {'Paper' => 0, 'Online' => 1}
@send_methods = SEND_METHODS
@send_methods.delete('Online')
SEND_METHODS
#=> {"Paper"=>0}
冻结哈希值可以避免这种情况:
SEND_METHODS = {'Paper' => 0, 'Online' => 1}.freeze
@send_methods = SEND_METHODS
@send_methods.delete('Online') #=> RuntimeError: can't modify frozen Hash
您必须dup
哈希(创建副本)才能对其进行修改:
@send_methods = SEND_METHODS.dup
@send_methods.delete('Online')
@send_methods
#=> {"Paper"=>0}
SEND_METHODS
#=> {"Paper"=>0, "Online"=>1}