variable rails programacion privados poo polimorfismo orientado objetos multiple instancia herencia con clases atributos ruby instance-variables class-variables class-instance-variables

programacion - ruby on rails poo



Variable de instancia de clase Ruby vs. variable de clase (4)

Como dijeron otros, las variables de clase se comparten entre una clase determinada y sus subclases. Las variables de instancia de clase pertenecen exactamente a una clase; sus subclases están separadas.

¿Por qué existe este comportamiento? Bueno, todo en Ruby es un objeto, incluso clases. Eso significa que cada clase tiene un objeto de la clase Class (o más bien, una subclase de Class ) que le corresponde. (Cuando dices class Foo , estás declarando realmente un Foo constante y asignándole un objeto de clase.) Y cada objeto Ruby puede tener variables de instancia, de modo que los objetos de clase también pueden tener variables de instancia.

El problema es que las variables de instancia en los objetos de la clase no se comportan realmente de la manera en que normalmente queremos que se comporten las variables de la clase. Por lo general, desea que una variable de clase definida en una superclase se comparta con sus subclases, pero no es así como funcionan las variables de instancia: la subclase tiene su propio objeto de clase y ese objeto de clase tiene sus propias variables de instancia. Entonces introdujeron variables de clase separadas con el comportamiento que es más probable que desee.

En otras palabras, las variables de instancia de clase son una especie de accidente del diseño de Ruby. Probablemente no deberías usarlos a menos que sepas específicamente que son lo que estás buscando.

Leí "¿ Cuándo se configuran las variables de instancia de Ruby? ", Pero me da mucho miedo cuándo utilizar las variables de instancia de la clase.

Las variables de clase son compartidas por todos los objetos de una clase, las variables de instancia pertenecen a un objeto. No queda mucho espacio para usar variables de instancia de clase si tenemos variables de clase.

¿Podría alguien explicar la diferencia entre estos dos y cuándo usarlos?

Aquí hay un ejemplo de código:

class S @@k = 23 @s = 15 def self.s @s end def self.k @@k end end p S.s #15 p S.k #23

Ahora entiendo, las variables de instancia de clase no se pasan a lo largo de la cadena de herencia.


Creo que el principal (¿solo?) Diferente es la herencia:

class T < S end p T.k => 23 S.k = 24 p T.k => 24 p T.s => nil

Las variables de clase son compartidas por todas las "instancias de clase" (es decir, subclases), mientras que las variables de instancia de clase son específicas solo de esa clase. Pero si nunca intenta extender su clase, la diferencia es puramente académica.


La variable de instancia de clase # está disponible solo para el método de clase y no para los métodos de instancia mientras que las variables de clase están disponibles tanto para los métodos de instancia como para los métodos de clase. Además, las variables de instancia de clase se pierden en la cadena de herencia, mientras que las variables de clase no lo son.

class Vars @class_ins_var = "class instance variable value" #class instance variable @@class_var = "class variable value" #class variable def self.class_method puts @class_ins_var puts @@class_var end def instance_method puts @class_ins_var puts @@class_var end end Vars.class_method puts "see the difference" obj = Vars.new obj.instance_method class VarsChild < Vars end VarsChild.class_method


Variable de instancia en una clase:

class Parent @things = [] def self.things @things end def things self.class.things end end class Child < Parent @things = [] end Parent.things << :car Child.things << :doll mom = Parent.new dad = Parent.new p Parent.things #=> [:car] p Child.things #=> [:doll] p mom.things #=> [:car] p dad.things #=> [:car]

Variable de clase:

class Parent @@things = [] def self.things @@things end def things @@things end end class Child < Parent end Parent.things << :car Child.things << :doll p Parent.things #=> [:car,:doll] p Child.things #=> [:car,:doll] mom = Parent.new dad = Parent.new son1 = Child.new son2 = Child.new daughter = Child.new [ mom, dad, son1, son2, daughter ].each{ |person| p person.things } #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll]

Con una variable de instancia en una clase (no en una instancia de esa clase) puede almacenar algo común para esa clase sin tener subclases que también las obtenga automáticamente (y viceversa). Con las variables de clase, tiene la comodidad de no tener que escribir self.class desde un objeto de instancia, y (cuando sea conveniente) también obtiene compartir automáticamente en toda la jerarquía de clases.

Fusionando estos juntos en un solo ejemplo que también cubre variables de instancia en instancias:

class Parent @@family_things = [] # Shared between class and subclasses @shared_things = [] # Specific to this class def self.family_things @@family_things end def self.shared_things @shared_things end attr_accessor :my_things def initialize @my_things = [] # Just for me end def family_things self.class.family_things end def shared_things self.class.shared_things end end class Child < Parent @shared_things = [] end

Y luego en acción:

mama = Parent.new papa = Parent.new joey = Child.new suzy = Child.new Parent.family_things << :house papa.family_things << :vacuum mama.shared_things << :car papa.shared_things << :blender papa.my_things << :quadcopter joey.my_things << :bike suzy.my_things << :doll joey.shared_things << :puzzle suzy.shared_things << :blocks p Parent.family_things #=> [:house, :vacuum] p Child.family_things #=> [:house, :vacuum] p papa.family_things #=> [:house, :vacuum] p mama.family_things #=> [:house, :vacuum] p joey.family_things #=> [:house, :vacuum] p suzy.family_things #=> [:house, :vacuum] p Parent.shared_things #=> [:car, :blender] p papa.shared_things #=> [:car, :blender] p mama.shared_things #=> [:car, :blender] p Child.shared_things #=> [:puzzle, :blocks] p joey.shared_things #=> [:puzzle, :blocks] p suzy.shared_things #=> [:puzzle, :blocks] p papa.my_things #=> [:quadcopter] p mama.my_things #=> [] p joey.my_things #=> [:bike] p suzy.my_things #=> [:doll]