ruby - objetos - tipos de variables clase instancia local
Diferencia entre las variables de clase y las variables de instancia de clase? (2)
Primero debe comprender que las clases también son instancias, instancias de la clase Class
.
Una vez que comprenda eso, puede comprender que una clase puede tener variables de instancia asociadas con ella, al igual que un objeto regular (de lectura: no de clase).
Hello = Class.new
# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")
# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"
Tenga en cuenta que una variable de instancia en Hello
está relacionada y es distinta de una variable de instancia en una instancia de Hello
hello = Hello.new
# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")
# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")
# see that it''s distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"
Una variable de clase, por otro lado, es un tipo de combinación de los dos anteriores, ya que está accesible en Hello
y sus instancias, así como en las subclases de Hello
y sus instancias:
HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new
Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"
Muchas personas dicen que se deben evitar class variables
debido al extraño comportamiento anterior, y recomiendan el uso de class instance variables
de class instance variables
lugar.
¿Alguien puede decirme sobre la diferencia entre las variables de clase y las variables de instancia de clase?
Una variable de clase ( @@
) se comparte entre la clase y todos sus descendientes. Los descendientes de la clase no comparten una variable de instancia de clase ( @
).
Variable de clase ( @@
)
Tengamos una clase Foo con una variable de clase @@i
, y accesadores para leer y escribir @@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
Y una clase derivada:
class Bar < Foo
end
Vemos que Foo y Bar tienen el mismo valor para @@i
:
p Foo.i # => 1
p Bar.i # => 1
Y cambiar @@i
en uno lo cambia en ambos:
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
Variable de instancia de clase ( @
)
Hagamos una clase simple con una variable de instancia de clase @i
y @i
para leer y escribir @i
:
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
Y una clase derivada:
class Bar < Foo
end
Vemos que aunque Bar hereda los @i
de @i
para @i
, no hereda @i
mismo:
p Foo.i # => 1
p Bar.i # => nil
Podemos establecer la @i
de Bar sin afectar la @i
de Foo:
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2