2012-02-23 10 views
9

Quiero saber cómo se comportan las variables de instancia de un módulo de Ruby en múltiples clases que lo 'mezclan' 'en'. Escribí un código de muestra para probarlo:¿Las variables de instancia de un módulo se comparten entre clase con mixin?

# Here is a module I created with one instance variable and two instance methods. 
module SharedVar 
    @color = 'red' 
    def change_color(new_color) 
    @color = new_color 
    end 
    def show_color 
    puts @color 
    end 
end 

class Example1 
    include SharedVar 
    def initialize(name) 
    @name  = name 
    end 
end 

class Example2 
    include SharedVar 
    def initialize(name) 
    @name  = name 
    end 
end 

ex1 = Example1.new("Bicylops") 
ex2 = Example2.new("Cool") 

# There is neither output or complains about the following method call. 
ex1.show_color 
ex1.change_color('black') 
ex2.show_color 

¿Por qué no funciona? ¿Y podría alguien explicar cuál será el comportamiento real de @color en múltiples instancias Example$?

Respuesta

11

En los módulos de Ruby y las clases son objetos, por lo que es posible establecer las variables de instancia para ellos.

module Test 
    @test = 'red' 
    def self.print_test 
    puts @test 
    end 
end 

Test.print_test #=> red 

Su error es pensar que el @color variable es la misma para:

module SharedVar 
    @color 
end 

y

module SharedVar 
    def show_color 
    @color 
    end 
end 

que no es.

En el primer ejemplo, la variable de instancia pertenece al objeto SharedVar y en el segundo ejemplo, la variable de instancia pertenece al objeto de incluir en el módulo.

Otra explicación por auto puntero. En el primer ejemplo, el auto puntero se establece en el objeto de módulo SharedVar, por lo que al escribir @color se hará referencia al objeto SharedVar y no habrá conexión con otro objeto. En el segundo ejemplo, se puede llamar al método show_color solo en algún objeto, es decir, ex1.show_color, por lo que el auto puntero apunta al objeto ex1. Entonces, en este caso, la variable de instancia se referirá al objeto ex1.

+0

¡Explicación bastante clara! Entonces, si el módulo que diseñé es para mezclar con otra clase. Debería definir la 'variable de instancia' dentro del' método de instancia', ¿es correcto mi entendimiento? – steveyang

+1

Sí, simplemente calcule cuál es el yo actual y luego puede comprender dónde se colocará la variable de instancia. – megas

+1

Gracias. Ahora mismo estoy aprendiendo Ruby, no a la parte del "yo actual". Parece un lenguaje más elegante que 'javaScript'. – steveyang

0

que ha incluido un módulo en el que una clase .. por lo que la instancia @color variable debe ser una variable de instancia tanto de la clase Ejemplo 1 y Ejemplo 2

lo tanto, si desea acceder a la variable @color significa supones para crear un objeto de la clase y luego se puede accesss que

para Ex

irb(main):028:0> ex1.change_color('black') 
=> "black" 
irb(main):029:0> ex1.show_color 
black 
irb(main):031:0> ex2.change_color('red') 
=> "red" 
irb(main):032:0> ex2.show_color 
red 
+0

Esto es exactamente lo que estoy haciendo. Pero tanto 'ex1' como' ex2' no tienen 'color' definido. – steveyang

Cuestiones relacionadas