2012-09-10 14 views
8

Suponiendo que se incluye un módulo, no extendido, ¿cuál es la diferencia entre la variable de instancia del módulo y la variable de clase?¿Cuál es la diferencia entre @ y @@ en un módulo?

No veo ninguna diferencia entre dos.

module M 
    @foo = 1 
    def self.foo 
    @foo 
    end 
end 
p M.foo 

module M 
    @@foo = 1 
    def self.foo 
    @@foo 
    end 
end 
p M.foo 

He estado usando como @@ @ dentro de un módulo, y recientemente vi otros códigos están utilizando @@ dentro de un módulo. Entonces pensé que podría haber estado usándolo incorrectamente.

Como no podemos crear instancias de un módulo, no debe haber diferencia entre @ y @@ para un módulo. ¿Me equivoco?

----------------------- agregó lo siguiente --------------------

Para responder algunas de las preguntas sobre comentarios y publicaciones, también probé lo siguiente.

module M 
    @foo = 1 
    def self.bar 
    :bar 
    end 

    def baz 
    :baz 
    end 
end 

class C 
    include M 
end 

p [:M_instance_variabies, M.instance_variables] # [@foo] 
p [:M_bar, M.bar] # :bar 

c = C.new 
p c.instance_variables 
p [:c_instance_variabies, c.instance_variables] # [] 
p [:c_baz, c.baz] :baz 
p [:c_bar, c.bar] # undefined method 

Cuando incluye un módulo dentro de una clase, las variables de clase de módulo y los métodos de clase no se definen en una clase.

+0

Soy bastante nuevo en Ruby, pero ¿por qué definirías un método de nivel de clase/módulo que devuelve una variable de instancia? Si el método está tratando con variables de instancia, ¿no debería ser un método de instancia, definido así como "def foo" en lugar de "def self.foo"? –

+0

No use variables de clase. Lo mejor es ni siquiera aprender a aprender. Son intrínsecamente defectuosos y no ofrecen nada que no puedas hacer con variables de instancia. Sinceramente espero que se eliminen de Ruby 2.0 –

+0

@JoshuaCheek: ¿Cómo funcionaría? Se supone que Ruby 2.0 es compatible con versiones anteriores de Ruby 1.9, entonces, ¿cómo propone eliminar una característica existente sin romper la compatibilidad hacia atrás? –

Respuesta

5

Las variables de clase se pueden compartir entre los módulos y las clases donde se incluyen estos módulos.

module A 
    @@a = 5 
end 

class B 
    include A 
    puts @@a # => 5 
end 

Mientras tanto, las variables de instancia pertenecen a self. Cuando se incluye el módulo A en la clase B, self objeto de A no es lo mismo que self objeto de B, por lo tanto, no podrá compartir variables de instancia entre ellos.

module A 
    @a = 5 
end 

class B 
    include A 
    puts @a # => nil 
end 
+0

esta es una muy buena respuesta. por lo que @@ es accessbile desde instancias que incluyen el módulo. pero @ no es accesible, ¿verdad? – allenhwkim

+0

sí, también puede observar el mismo comportamiento con la herencia, p. Las clases padre/hijo pueden compartir @@, y no @ (si hablamos del alcance de la clase, no de su objeto). –

0

encontré this SO post que habla de cómo crear clases variables en los módulos, "son compatibles de forma nativa". One commenter incluso dice que el nombre 'variable de clase' es engañoso ya que las clases son solo módulos con algunos poderes extra.

Todo lo que estoy seguro es que casi todos los artículos que he leído sobre variables de clase piensan que son malos y que los evitan a toda costa debido a los extraños problemas de herencia que pueden surgir.

Cuestiones relacionadas