Ruby のインスタンス変数とクラス変数

インスタンス変数は再帰させるとどうなるのかな。

class Counter
  def initialize(c = 0)
    @c = c
  end
  
  def count
    return if @c > 3
    puts @c
    @c += 1
    count
  end
end

i = Counter.new
j = Counter.new(1)
i.count
j.count

結果

0
1
2
3
1
2
3

インスタンス変数は、クラスの中で使えるグローバル変数みたいなものか。

class Counter
  def initialize
    @@c = 0
  end
  
  def count
    3.times do
      puts @@c
      @@c += 1
    end
  end
end

i = Counter.new
j = Counter.new
i.count
j.count

結果

0
1
2
3
4
5

クラス変数は、そのクラスの全部のインスタンスで共通なわけだ。


クラスの中にクラスを書いてみる

class A
  def initialize
     @a = "outside"
  end
  
  def op
    j = B.new
    j.op
    p @a
  end
  
  class B
    def initialize
      @a = "inside"
    end
    
    def op
      p @a
    end
  end
end

i = A.new
i.op

の結果は

"inside"
"outside"

だけれど、

class A
  def initialize
     @a = "outside"
  end
  
  def op
    p @a
  end
  
  class B
    def initialize
      @a = "inside"
    end
    
    def op
      p @a
    end
  end
end

i = A.new
i.op
j = B.new
j.op

の結果は

"outside"
C:/Users/***/Ruby/b.rb:23:in `<main>': uninitialized constant B (NameError)

とエラーになる。しかし、最後の j = B.newj = A::B.new と替えれば、結果は

"outside"
"inside"

となる。