2012-02-23 17 views
9

Chcę wiedzieć, jak zachowują się zmienne instancji modułu Ruby w wielu klasach, które "mieszają" je w ". Napisałem przykładowy kod, aby go przetestować:Czy zmienne instancji modułu są wspólne dla klasy z mixinem?

# 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 

Dlaczego to nie działa? A może ktoś mógłby wyjaśnić, co będzie rzeczywiste zachowanie @color w wielu instancjach Example$?

Odpowiedz

11

W Ruby modułów i klas są obiektami, więc jest to możliwe, aby ustawić zmienne instancji dla nich.

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

Test.print_test #=> red 

Twój błędem jest myślenie, że zmienna @color jest taka sama dla:

module SharedVar 
    @color 
end 

i

module SharedVar 
    def show_color 
    @color 
    end 
end 

co nie jest.

W pierwszym przykładzie, zmienna instancji należy do obiektu SharedVar aw drugim przykładzie zmienna instancji należy do obiektu, który to moduł w.

Innym wyjaśnieniem przez siebie wskaźnika. W pierwszym przykładzie wskaźnik self jest ustawiony na obiekt modułu SharedVar, więc wpisanie @color odwoła się do obiektu SharedVar i nie ma połączenia z innym obiektem. W drugim przykładzie, metoda show_color może być wywołana tylko na pewnym obiekcie, tj. ex1.show_color, więc wskaźnik self self wskaże obiekt ex1. W tym przypadku zmienna instancji będzie odnosić się do obiektu ex1.

+0

Dość jasne wyjaśnienie! Więc jeśli zaprojektowany przeze mnie moduł jest przeznaczony do mieszania z inną klasą. Powinienem zdefiniować 'instancyjną zmienną' wewnątrz' metody instancji', czy moje zrozumienie jest poprawne? – steveyang

+1

Tak, po prostu obliczyć, co jest aktualnym self, a następnie można zrozumieć, gdzie zostanie umieszczona zmienna instancji. – megas

+1

Dzięki. Właśnie uczę się Ruby, a nie "bieżącej jaźni". Wydaje się być bardziej eleganckim językiem niż "javaScript". – steveyang

0

Masz włączone w moduł do klasy .. więc instancja zmiennej @color powinien być instancją zmienna zarówno klasa Przykład1 i Przykład2

Więc jeśli chcesz uzyskać dostęp do zmiennej @color oznacza myślisz utworzyć obiekt do klasy, a następnie można dostępu jak to

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

To jest dokładnie to, co robię. Ale zarówno 'ex1', jak i' ex2' nie mają zdefiniowanego 'color'. – steveyang