rubyのクロージャをcallするために一度変数に入れる理由を知りたい


rubyのクロージャでprocを変数に入れる理由を知りたいです。

[code]

    def a
        n = 0
        proc do 
            n += 1
        end
    end
    
[/code]

例えば上のような実行するたびに1を増やすクロージャを返すメソッドで

[code]

    a.call # => 1
    a.call # => 1
    b = a
    b.call # => 1
    b.call # => 2
    
[/code]

aメソッドに直接callをしても1ずつ増えていかないが、

**b** に **a** メソッドをいれてから **call** することでちゃんと機能する理由がわかりません

**a.call** だと、メソッド **a** を起動してしまい、 **n = 0** が実行されているからでしょうか?  
これが、一度変数に入れることで回避されるのは、

[code]

    b = a
    b.call 
    
[/code]

の場合  
**a** メソッド内の **proc** 部分だけが呼ばれているという解釈でよろしいでしょうか?




合ってます。詳しくいうと次のようになってます。

次の3行では a が3回呼ばれ、  
つまり n = 0 が3回実行され、  
新しい Proc が3回作られ、  
それぞれの Proc に対して1回ずつ call を呼んでいます。

a.call  
a.call  
a.call

これに対して次の4行では a は1回だけ呼ばれ、  
つまり n = 0 は1回だけ実行され、  
新しい Proc は1回だけ作られ、  
その1個だけの Proc に3回 call を呼んでいます。

b = a  
b.call  
b.call  
b.call

言い換えると b = a は  
a というメソッドに b という別名をつけているのではなく、  
a というメソッドの返した値を b に代入しています。




メソッド `a` は実行される度に新規の closure を返します。

[code]

    irb(main)> a == a
    => false
    irb(main)> a == a
    => false
    irb(main)> a == a
    => false
    
[/code]

一方、`b = a` とした場合の `b` は `a` の実行によって作成された closure になります。

[code]

    irb(main)> b = a
    => #<Proc:0x000055562ac72510 (irb):3>
    irb(main)> b == b
    => true
    
    irb(main)> c = a
    => #<Proc:0x000055562ac89788 (irb):3>
    irb(main)> c == b
    => false
    
[/code]

