¿Por qué ruby ​​attr_accessor no funciona en este caso? [duplicar]

Me gustaría entender por qué esto no funcionaría. Conozco la noción de attr_accessor.

class MyClass
  attr_accessor :num

  def initialize(num = 0)
    @num = num
  end

  def calulate
    while num < 100
      num = num + 1
    end

    puts num
  end

end

c = MyClass.new
c.calulate

Esto me da error.

my_class.rb:11:in `calulate': undefined method `+' for nil:NilClass (NoMethodError)

sin embargo, si cambio numa @num. funciona. ¿Alguien puede explicar esto?

Actualizar

Además, si ejecuto esta línea de código, devolverá la misma identificación.

puts num.object_id
puts @num.object_id
puts self.num.object_id

resultado

1
1
1
Answer

El problema viene de la línea. num = num + 1

El acceso funciona, pero para asignar a un accesor desde dentro de una clase, tendría que hacer

self.num = num + 1

Lo que está haciendo la primera vez que ejecuta num = num + 1 es crear una nueva variable numy sombrear el método.

Entonces, en el bucle while, cada acceso a numse referiría a su nueva variable, haciendo una asignación explícita para self.num=que Ruby sepa que no está creando una nueva variable.