2016-07-02 12 views
6

Czytam moją książkę o rubinach. Patrząc na poniższy kod,Jakie kryteria uzasadniają użycie Modułu ponad klasą w Ruby?

module Destroy 
    def destroy(anyObject) 
    @anyObject = anyObject 
    puts "I will destroy the object: #{anyObject}" 
    end 
end 

class User 
    include Destroy 
    attr_accessor :name, :email 
    def initialize(name,email) 
    @name = name 
    @email = email 
    end 
end 

my_info = User.new("Bob","[email protected]") 
puts "So your name is: #{my_info.name} and you have email #{my_info.email}" 

user = User.new("john","[email protected]") 
user.destroy("blah") 

Mogłem właśnie stworzyć inną metodę w mojej klasie. Dlaczego miałbym to robić? Dlaczego miałbym chcieć użyć modułu? To nie jest tak, jak umieszczanie tego w innych klasach jest łatwiejsze niż zwykłe dziedziczenie.

+0

Dziedziczenie nie jest jedynym sposobem udostępniania funkcji i często nie jest ani praktyczne, ani możliwe. –

+0

Prawdopodobny duplikat [Różnica między klasą a modułem] (http://stackoverflow.com/questions/151505/difference-between-a-class-and-a-module) – SoAwesomeMan

Odpowiedz

3

Możesz myśleć o module, jego metodach i stałych, ponieważ zapewnia on więcej funkcji i czynności użytkowych, które możesz dołączyć do innych obiektów, jak uważasz za stosowne. Na przykład, jeśli chcesz korzystać z funkcji zniszczenia w obiektach Foo i Bar byś zrobił podobnie:

class Foo 
    include Destroy 
    # other code below 
end 

class Bar 
    include Destroy 
    # other code below 
end 

Teraz każdy Foo lub Bar obiekt ma dostęp do wszystkich metod lub stałych wewnątrz od zniszczenia.

Moduły definiują przestrzeń nazw, piaskownicę, w której mogą być używane metody i stałe, bez obawy, że zostaną nadepnięte przez inne metody i stałe. ruby docs przechodzi w bardziej szczegółowo na ten temat i zawiera dobry przykład praktycznego od kiedy chcesz go używać, jak widać poniżej:

module Debug 
    def whoAmI? 
    "#{self.type.name} (\##{self.id}): #{self.to_s}" 
    end 
end 
class Phonograph 
    include Debug 
    # ... 
end 
class EightTrack 
    include Debug 
    # ... 
end 
ph = Phonograph.new("West End Blues") 
et = EightTrack.new("Surrealistic Pillow") 
ph.whoAmI? » "Phonograph (#537766170): West End Blues" 
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow" 

W tym przykładzie, każda klasa, która zawiera Debug ma dostęp do metody whoAmI? i inne metody i stałe, które obejmuje debugowanie bez konieczności ponownego definiowania go dla każdej klasy.

+0

"# {self.type.name} (\ ## {self.id}): # {self.to_s}", co oznacza ta linia? Moja książka wspomina o sobie bardzo krótko, punkty własne do modułu Debuguj tutaj, prawda? –

+0

Szczególnie znaki ##, nigdy nie widziałem, że w moim życiu, jestem tylko familar z # {zmienna} –

+0

@ cresjoy To ciąg znaków zawierający nazwę typu, identyfikator i ciąg znaków reprezentujących obiekt. Dodatkowe # służy tylko do formatowania, jak widać w dwóch ostatnich liniach przykładu, dlatego jest unikane. Ja używa obiektu, który został wywołany w celu zwrócenia informacji. – Dom

2

Niektóre języki programowania, takie jak C++, Perl i Python, umożliwiają jednej klasie dziedziczenie z wielu innych klas; nazywa się to dziedziczeniem wielokrotnym. Ruby nie obsługuje dziedziczenia wielokrotnego. Oznacza to, że każda klasa może dziedziczyć tylko z jednej innej klasy. Istnieją jednak przypadki, w których klasa mogłaby odnieść korzyść poprzez nabycie metod zdefiniowanych w wielu innych klasach. Jest to możliwe dzięki użyciu konstrukcji zwanej modułem.

Moduł jest nieco podobny do klasy, z tym wyjątkiem, że nie obsługuje dziedziczenia ani tworzenia instancji. Jest najczęściej używany jako pojemnik do przechowywania wielu metod. Jednym ze sposobów użycia modułu jest zastosowanie instrukcji include lub extend w klasie. W ten sposób klasa uzyskuje dostęp do wszystkich metod i obiektów zdefiniowanych w module. Mówi się, że moduł jest wymieszany w klasie. Tak więc mixin to tylko moduł zawarty w klasie. Pojedynczy moduł może być mieszany w wielu klasach, a jedna klasa może mieszać się w wielu modułach; tak więc, wszelkie ograniczenia nałożone przez pojedynczy model dziedziczenia Rubiego są eliminowane przez funkcję mixin o numerze.

Do wyświetlania nazw można również używać modułów. Zostało to wyjaśnione w this post at the Practicing Ruby website.

+0

Dobrze, ale powinieneś powiedzieć coś o moduły, które nie są przeznaczone do mieszania, a jedynie do umieszczania metod pomocniczych (modułów) (zdefiniowane 'def self.mod_method ...'), które mogą być używane przez różne klasy. –

+0

Hmm ... Zupełnie nie wiedziałem o tym. Więc twoje powiedzenie, że jeśli klasa B dziedziczy z klasy A, klasa C nie może dziedziczyć z klasy A? –

+0

@cresjoy Nie. Obie klasy B i C mogą odziedziczyć po A. Jednak B nie może dziedziczyć zarówno z A, jak i C. Każda klasa może dziedziczyć tylko z jednej innej klasy. Jednak jedna klasa może być dziedziczona przez wiele innych klas. – BrunoFacca

0

Piszemy moduł w tym samym pliku co klasa, ale niekoniecznie w klasie, ale w każdym razie.

Dla mnie istnieją 3 powodów, aby użyć modułu (więcej szczegółów here):

  1. Moduły zapewniają nazw i zapobiec kolizji nazw.
  2. Moduły wdrażają obiekt mixin.
  3. Gdy masz bardzo złożoną i gęstą klasę, możesz podzielić ją na moduły i uwzględnić w głównej klasie.

Twój przykład jest dość prosty, bardziej sensownym byłoby napisanie metody w samej klasie, ale spróbuj wyobrazić sobie złożony scenariusz.

+1

Twoja 1 jest tutaj nieistotna. 2 jest również nieistotne, jeśli celem jest włączenie obiektu do wielu klas, a jeśli nie, to nic nie wyjaśnia. 3 jest istotną sprawą, o której mowa, ale nie wyjaśnia, dlaczego chcesz to zrobić. – sawa

+0

Niezależnie od tego scenariusza, myślę, że ważne jest, aby OP wiedział, dlaczego i kiedy użyje modułu. – fabriciofreitag

Powiązane problemy