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