Las variables de clase (como @@count
)
son compartidas por una clase y todas sus subclases.
Si una variable @@a
es definida por una clase A
entonces cualquier subclase B
de A
puede usar dicha variable.
Si una subclase asigna un valor a una variable de clase en uso por una superclase no es que cree una copia de dicha variable sino que altera el valor de la variable de la superclase. Ese será el valor que vean todas las otras subclases de la superclase.
Este ejemplo ilustra el comportamiento:
[~/srcLPP/inheritance]$ cat InheritanceAndClassVariables.rb class A @@value = 1 def A.value @@value end end puts A.value # 1 class B < A @@value = 2 end puts A.value # 2 puts B.value # 2 class C < A; @@value = 3; end puts B.value # 3 puts C.value # 3 puts "A.class_variables = #{A.class_variables.inspect}" # [:@@value] puts "B.class_variables = #{B.class_variables.inspect}" # [] puts "C.class_variables = #{C.class_variables.inspect}" # []Al ejecutar tenemos:
[~/srcLPP/inheritance]$ ruby InheritanceAndClassVariables.rb 1 2 2 3 3 A.class_variables = [:@@value] B.class_variables = [] C.class_variables = []Por esta razón es preferible usar variables de instancia de la clase en vez de variables de clase. Nótese que siempre podemos averiguar las variables de clase de una clase mediante el método
class_variables
.
Observa la diferencia cuando se usan variables de instancia de la clase:
13:11][~/Dropbox/src/ruby/rubytesting/TheRubyProgrammingLanguage/Chapter7ClassesAndModules]$ cat InheritanceAndClassInstanceVariables.rb class A @value = 1 def self.value @value end end puts A.value # 1 class B < A @value = 2 end puts A.value # 1 puts B.value # 2 class C < A; @value = 3; end puts B.value # 2 puts C.value # 3
[13:12][~/Dropbox/src/ruby/rubytesting/TheRubyProgrammingLanguage/Chapter7ClassesAndModules]$ ruby InheritanceAndClassInstanceVariables.rb 1 1 2 2 3
Casiano Rodriguez León 2015-01-07