Une variable avec le préfixe @
est une variable d'instance, tandis que le préfixe @@
est une variable de classe. Découvrez l'exemple suivant; sa sortie est dans les commentaires à la fin de l' puts
lignes:
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
Vous pouvez voir qu' @@shared
est partagé entre les classes; le réglage de la valeur dans une instance de l'un des changements de la valeur pour toutes les autres instances de cette classe, et même des enfants de classes, d'où une variable nommée @shared
, avec un @
, ne serait pas.
[Mise à jour]
Comme Phrogz mentionne dans les commentaires, il s'agit d'un idiome en Ruby pour suivre le niveau de la classe de données avec une variable d'instance de la classe elle-même. Cela peut être un sujet délicat pour envelopper votre esprit autour, et il ya beaucoup d' autres lectures sur le sujet, mais pensez à ce sujet que la modification de l' Class
classe, mais seulement l'instance de l' Class
classe que vous travaillez avec. Un exemple:
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
J'ai inclus l' Square
exemple (qui, de sorties nil
) pour démontrer que cela peut ne pas se comporter à 100% comme vous vous attendez; l' article que j'ai lié ci-dessus a beaucoup d'informations supplémentaires sur le sujet.
Aussi garder à l'esprit que, comme avec la plupart des données, vous devez être extrêmement prudent avec les variables de classe dans un environnement multithread, comme par dmarkow commentaire.