2012-11-05 17 views
11

Chciałabym wiedzieć, czy mogę zmusić to się stałoRuby Bez ograniczeń Metody: Czy można wymusić powiązanie z instancjami innych klas?

class A 
    def bomb ; "bomb" ; end 
end 

class B ; end 

bomb = A.instance_method(:bomb) 

b = B.new 
bomb.bind(b) 

obecnie to rzuca TypeError błędzie: Argument wiążą musi być instancją

Uważam to bardzo ograniczające dotyczące tego, co mogę zrobić z tymi niezwiązanymi metodami możliwości są nieco ograniczone. W takich przypadkach (i nie mówię tylko o funkcjach idempotentnych) miałoby to sens, prawda? I błąd wykonania byłby wystarczający, w przypadku, gdybym obsługiwał zmienne z A, które nie są replikowane w B. Naprawdę chciałbym wiedzieć, jak wymusić to wiązanie.

+0

coś ciekawego, że jest możliwa: 'Object.instance_method (: to_s). .bind ("Hello World") nazywamy # =>„# "'. Nie sądzę jednak, że można wymusić wiązanie w twoim przykładzie. –

+2

Tak, dzieje się tak, ponieważ łańcuch String dziedziczy po Object i można powiązać metody klas nadrzędnych z instancjami klasy potomnej. Przykład: klasa A; def t; "A"; koniec ; koniec ; klasa B ChuckE

+0

jeśli 'A' byłby' modułem', to jest to możliwe w ruby ​​2 –

Odpowiedz

2

Nie można powiązać instancji klasy z metodą innej klasy. O ile instancja nie jest obiektem tej klasy lub jej podklas.

I to też jest oczywiste, szczegóły jednej klasy nie mogą być przeniesione do instancji innej klasy. Może być związany tylko z tą instancją, która jest upoważniona do przenoszenia tej informacji, która jest instancją tej klasy lub jej podklasy.

Dlatego też ruby ​​utrzymuje enkapsulację nie wiążąc metody danej klasy z instancją innej klasy.

0

Metody Method i UnboundMethod oczekują, że obiekt wiązania musi być podklasą oryginalnej klasy, do której odwołuje się metoda. Konwersja metody do proc pozbawia się ograniczenia podklasy, ale tylko metoda ma zaimplementowaną metodę to_proc.

class A 
    def bomb ; "bomb" ; end 
end 

class B ; end 

bomb = A.new.method(:bomb) 

B.send(:define_method, :bomb_in_b, &bomb) #converting to proc 

b = B.new 
puts b.bomb_in_b 

Testowany w Ruby 2.2.3

Powiązane problemy