我只是想在以下代码中理解 destroy
方法的行为:
更新:请注意我的目的是了解行为,而不是将nil分配给变量的直接解决方案。
def conf
@conf ||= { 'foo' => { 'bar' => 'baz' } }
end
def destroy
conf = nil
end
def change
conf['foo']['bar'] = 'meh'
end
def add
conf['foo']['abc'] = 'moo'
end
以下是调用add
方法的输出:
add
pp conf
# {"foo"=>{"bar"=>"baz", "abc"=>"moo"}}
change
方法
change
pp conf
# {"foo"=>{"bar"=>"meh"}}
destroy
方法
destroy
pp conf
# {"foo"=>{"bar"=>"baz"}}
那么,为什么destroy
导致conf
nil
def foo
@foo ||= "bar"
end
def destroyfoo
foo = nil
end
def changefoo
foo = "baz"
end
?
另一个相关的片段,这次标量不是哈希:
changefoo
调用destroyfoo
和 destroyfoo
puts foo
# "bar"
时的结果:
changefoo
puts foo
# "bar"
...
{{1}}
任何关于可能发生的事情的指针在这两种情况下都会有用。
答案 0 :(得分:2)
您的destroy
,destroyfoo
和changefoo
方法都只是分配给局部变量,并且不会导致调用存取方法。
change
方法有效的原因是conf['foo']['bar'] = 'meh'
调用conf
方法获取@conf
,然后调用[]
返回对象的方法,然后在第一级哈希上调用[]=
方法。同样适用于add
。
这与conf =
另外,为了完整起见,请注意,即使您为@conf
创建了一个attr writer(使用attr_writer
或者自己编写conf=
方法),也请注意像conf = nil
一样仍然会引用一个局部变量,并且不会调用你的方法。您需要使用self.conf=
才能消除歧义。
答案 1 :(得分:1)
这是因为您的destroy
方法正在创建名为conf
的变量。 Ruby能够根据您的调用方式判断什么是方法,什么是变量。
irb> puts "Lincoln"
Lincoln
irb> puts = "Washington"
irb> puts "Polk"
Polk
irb> puts puts
Washington
这里发生的事情是有一个名为puts
的方法,并且有一个名为puts
的变量。 Ruby会根据您的调用方式确定您要使用的内容。在最后一个示例中,左puts
是方法调用,而右puts
是变量。
请注意,一旦方法块执行完毕,变量destroy
创建将退出范围。因此,在您的情况下,尝试在方法之外的任何时间(在主范围内)调用conf
将是对方法的调用。