Una variable con el prefijo @
es un instancia de variable, mientras que uno con el prefijo @@
es una clase variable. Mira el siguiente ejemplo; su salida es en los comentarios al final de las líneas puts
:
class Test
@@shared = 1
def value
@@shared
end
def value=(value)
@@shared = value
end
end
class AnotherTest < Test; end
t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2
x = Test.new
puts "x.value is #{x.value}" # 2
a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3
Se puede ver que @@shared
se comparte entre las clases; establecer el valor en una instancia de uno cambia el valor para todas las demás instancias de esa clase e incluso clases secundarias, donde una variable llamada @shared
, con una @
, no lo sería.
[Actualización]
Como Phrogz menciona en los comentarios, es un idioma común en Ruby para realizar un seguimiento de datos de nivel de clase con una instancia de variable en la propia clase. Esto puede ser un tema difícil para su mente, y hay un montón de additional reading sobre el tema, pero piense en ello como la modificación de la clase Class
, pero solo la instancia de la clase Class
con la que está trabajando. Un ejemplo:
class Polygon
class << self
attr_accessor :sides
end
end
class Triangle < Polygon
@sides = 3
end
class Rectangle < Polygon
@sides = 4
end
class Square < Rectangle
end
class Hexagon < Polygon
@sides = 6
end
puts "Triangle.sides: #{Triangle.sides.inspect}" # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides: #{Square.sides.inspect}" # nil
puts "Hexagon.sides: #{Hexagon.sides.inspect}" # 6
que incluyó la Square
ejemplo (que da salida a nil
) para demostrar que esto no se puede comportar 100% como se esperaba; el article I linked above tiene mucha información adicional sobre el tema.
También tenga en cuenta que, como con la mayoría de los datos, debe tener mucho cuidado con las variables de clase en un multithreaded environment, según el comentario de dmarkow.
No lo sé, pero tengo la sensación de que me está mirando. Tengo un poco de miedo para codificar en Ruby ahora ... – corsiKa
TL; DR para el público: 99 veces de cada 100, usaría variables de "instancia de clase" (métodos '@' dentro de 'self') no variables de clase ('@@'). Vea la letanía de razones por las cuales en las respuestas a continuación. – WattsInABox