3

次のコードでメソッドの動作を理解しようとしています。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"}}

では、なぜ を持たないdestroyconfでしょnilうか?

関連する別のスニペット。今回はハッシュではなくスカラーを使用します。

    def foo
      @foo ||= "bar"
    end

    def destroyfoo
      foo = nil
    end

    def changefoo
      foo = "baz"
    end

呼び出し時の結果changefoodestroyfoo両方:

    destroyfoo
    puts foo
    # "bar"

...

    changefoo
    puts foo
    # "bar"

何が起こっているのかについての指針は、どちらの場合にも役立ちます。

4

2 に答える 2

2

destroydestroyfooおよびchangefooメソッドはすべてローカル変数に割り当てられているだけであり、アクセサー メソッドの呼び出しにはなりません。

changeメソッドが機能する理由はconf['foo']['bar'] = 'meh'confget@confへのメソッドの呼び出し[]、次に返されたオブジェクトのメソッドの呼び出し、そして[]=第 1 レベルのハッシュのメソッドの呼び出しであるためです。についても同様ですadd

これは、次のような直接代入とは異なりますconf =

また、完全を期すために、(自分でメソッド@confを使用attr_writerまたは作成して)属性ライターを作成した場合でも、次のような行はローカル変数を参照し、メソッドを呼び出さないことに注意してください。明確にするために使用する必要があります。conf=conf = nilself.conf=

于 2012-11-29T15:02:34.433 に答える
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メソッド ブロックの実行が完了すると、変数 create がスコープから除外されることに注意してください。したがって、あなたの場合、confメソッドの外(メインスコープ上)でいつでも呼び出そうとすると、メソッドの呼び出しになります。

于 2012-11-29T14:59:48.613 に答える