2012-09-26 9 views
6

Próbuję zrozumieć zachowanie instrukcji include, gdy jest używane w wielu Mixinsach. Oznacza to, że mam te oświadczenia:Opis działania instrukcji `include` dla" kolejnych "modułów mixin

class Article < ActiveRecord::Base 
    include DoubleIncludedModule 
    include AModule 

    # ... 
end 

module AModule 
    include DoubleIncludedModule 

    # ... 
end 

module DoubleIncludedModule 
    # ... 
end 

Ile razy będzie DoubleIncludedModule zawarte w klasie Article? To znaczy, ponieważ "późniejsze" włączenie DoubleIncludedModule (najpierw w klasie Article, a następnie w AModule włączonej przez samą klasę Article) będzie problemem "podwójnego włączenia" automatycznie obsługiwanego przez Ruby lub spowoduje, że DoubleIncludedModule (błędnie) zostanie włączony dwa razy?

Oczywiście, chciałbym dołączyć moduł DoubleIncludedModuletylko jeden raz. Jak mogę to zrobić (może za pomocą niektórych metod Ruby on Rails) we właściwy sposób?

+3

Tylko dlatego, że używasz Railsów, nie oznacza to, że pytanie ma coś wspólnego z Railsami. Railsy nie zmieniają sposobu działania 'include'. To jest pytanie wyłącznie rubinowe. –

+1

@Andrew Marshall - Możliwe, że istnieją pewne metody Ruby on Rails, które mogą pomóc w rozwiązaniu niektórych problemów - jak w pytaniu. – Backo

Odpowiedz

9

Odpowiem na przykładzie:

module M 
    def self.included base 
    puts "M included in #{base}" 
    end 
end 

module N 
    include M 

    def self.included base 
    puts "N included in #{base}" 
    end 
end 

class C 
    include M 
    include N 
end 

p C.ancestors 

drukuje

M included in N 
M included in C 
N included in C 
[C, N, M, Object, Kernel, BasicObject] 

Jak widzimy, M wliczone jest tylko raz w C. Chociaż był on zawarty w N, to był również zawarty w C. Czy to ma znaczenie? Prawdopodobnie nie. Każdy nadal występuje tylko raz w łańcuchu przodków, a wszelkie metody zostałyby zastąpione równoważnymi implementacjami - tj. Zasadniczo nie jest opcją. Jeśli nie robisz czegoś egzotycznego z hakiem included, prawdopodobnie nic nie zauważysz.