template pass for code blocks argument ruby syntax instance-variables class-variables

pass - ruby template



¿Qué significa @@ variable en Ruby? (5)

¿Qué son las variables de Ruby precedidas con el doble en los signos ( @@ )? Mi comprensión de una variable precedida de un signo at es que es una variable de instancia, como esta en PHP:

Versión de PHP

class Person { public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } }

Ruby equivalente

class Person def set_name(name) @name = name end def get_name() @name end end

¿Qué significa el doble en sign @@ , y cómo difiere de un solo en el signo?


@ = variable de instancia donde como variable @@ = class

la variable de instancia es similar, que se comparte con la instancia / objetos de una clase para acceder a la variable de instancia que necesitamos para definir los setters y getters para esa variable de instancia

mientras que la variable de clase es similar, que se comparte entre todas las instancias / objetos de una clase o, en otras palabras, se puede decir que es una variable global, por lo que se puede acceder globalmente a la variable global


@ y @@ en los módulos también funcionan de manera diferente cuando una clase amplía o incluye ese módulo.

Así que dado

module A @a = ''module'' @@a = ''module'' def get1 @a end def get2 @@a end def set1(a) @a = a end def set2(a) @@a = a end def self.set1(a) @a = a end def self.set2(a) @@a = a end end

Luego obtienes los resultados que se muestran a continuación como comentarios

class X extend A puts get1.inspect # nil puts get2.inspect # "module" @a = ''class'' @@a = ''class'' puts get1.inspect # "class" puts get2.inspect # "module" set1(''set'') set2(''set'') puts get1.inspect # "set" puts get2.inspect # "set" A.set1(''sset'') A.set2(''sset'') puts get1.inspect # "set" puts get2.inspect # "sset" end class Y include A def doit puts get1.inspect # nil puts get2.inspect # "module" @a = ''class'' @@a = ''class'' puts get1.inspect # "class" puts get2.inspect # "class" set1(''set'') set2(''set'') puts get1.inspect # "set" puts get2.inspect # "set" A.set1(''sset'') A.set2(''sset'') puts get1.inspect # "set" puts get2.inspect # "sset" end end Y.new.doit

Por lo tanto, use @@ en los módulos para las variables que desee que sean comunes a todos sus usos, y use @ en los módulos para las variables que desee separar para cada contexto de uso.


Una variable con el prefijo @ es una variable de instancia , mientras que una prefijada con @@ es una variable de clase . Mira el siguiente ejemplo; su salida está en los comentarios al final de las líneas de 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

Puedes 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.

[Actualizar]

Como Phrogz menciona en los comentarios, es una expresión común en Ruby para rastrear datos de nivel de clase con una variable de instancia en la clase misma . Este puede ser un tema difícil para su mente, y hay mucha lectura adicional sobre el tema, pero piense en ello como una modificación de la clase Class , pero solo en la instancia de la clase Class 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

Incluí el ejemplo de Square (que da como resultado nil ) para demostrar que esto puede no comportarse al 100% como esperabas; el artículo que he vinculado anteriormente tiene mucha información adicional sobre el tema.

También tenga en cuenta que, como con la mayoría de los datos, debe ser extremadamente cuidadoso con las variables de clase en un entorno multiproceso , según el comentario de dmarkow.


@ - Variable de instancia de una clase
@@ - Variable de clase, también llamada variable estática en algunos casos

Una variable de clase es una variable que se comparte entre todas las instancias de una clase. Esto significa que solo existe un valor de variable para todos los objetos instanciados de esta clase. Si una instancia de objeto cambia el valor de la variable, ese nuevo valor esencialmente cambiará para todas las demás instancias de objetos.

Otra forma de pensar al pensar en variables de clase es como variables globales dentro del contexto de una sola clase. Las variables de clase se declaran prefijando el nombre de la variable con dos @ caracteres ( @@ ). Las variables de clase deben inicializarse en el momento de la creación


@@ denota una variable de clase, es decir, puede heredarse.

Esto significa que si crea una subclase de esa clase, heredará la variable. Entonces, si tienes una clase Vehicle con la variable de clase @@number_of_wheels entonces si creas una class Car < Vehicle entonces también tendrá la variable de clase @@number_of_wheels