解释方法的行为&具有相同名称的变量&红宝石的其他属性

时间:2012-11-29 14:40:24

标签: ruby variables hash methods scalar

我只是想在以下代码中理解 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}}

任何关于可能发生的事情的指针在这两种情况下都会有用。

2 个答案:

答案 0 :(得分:2)

您的destroydestroyfoochangefoo方法都只是分配给局部变量,并且不会导致调用存取方法。

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将是对方法的调用。