2017-11-28 2 views

Antwort

2

Es gibt ein paar Dinge im Auge zu behalten hier:

  • Wenn Sie Modul-Methoden mit dem self Präfix erklären, dass sie in der Lage bedeutet, direkt auf dem Modul aufgerufen werden, wie A.a1, aber es bedeutet auch, dass sie nicht mit include importiert werden. Jene, die ohne Selbstangabe deklariert wurden, sind "Mix-in-Methoden" oder solche, die automatisch unter include importiert werden.
  • Wenn Sie include mehr als ein Modul, das eine Methode definiert, wird das letzte Modul enthalten sein, das tatsächlich aufgerufen wird.

Das Update ist hier entweder def self.a1-def a1 in module A zu verändern oder mit A.a1 stattdessen direkt aufrufen. Wenn B auch a1 definiert, hat es die Priorität , es sei denn Sie include B zuerst, so dass es niedrigere Priorität hat.

+0

Viele Tutorials machen Ruby Mixins extrem kompliziert, und ich verstehe wirklich nicht warum. 'include' macht den Mix zur Superklasse. Und das ist es. Es gibt buchstäblich nichts mehr über Ruby Mixins zu verstehen. Es ist nur Standard langweilig alte Vererbung. –

+0

@ JörgWMittag Das Verwirrende an ihnen ist, wenn du nie eine Sprache benutzt hast, die diese Art von selektiver Komposition erlaubt. Die meisten Menschen sind an die einfache oder mehrfache Vererbung gewöhnt, und diese sind normalerweise zum Zeitpunkt der Definition gesperrt. Mit 'include' können Sie zu jeder Zeit weitere Vererbungen vom Typ" Superklasse "beliebig hinzufügen. Das wirkt zunächst sehr merkwürdig, so wie man das auch an einzelnen Objekten machen kann. – tadman

0

Wenn Sie diese Art der Sache wissen, vor der Zeit geschehen wird, können Sie alias verwenden, wie Sie Module einschließlich sind (beachten Sie, das die Methodendefinitionen def self.a1-def a1 ändert, so dass sie richtig als Instanzmethoden sind enthalten):

module A 
    def a1 
    puts "I am defined in A" 
    end 
end 

module B 
    def a1 
    puts "I am defined in B" 
    end 
end 

class Sample 
    include A 
    alias :a_a1 :a1 
    include B 
    alias :b_a1 :a1 
end 

samp = Sample.new 
samp.a_a1 
samp.b_a1 
samp.a1 

läuft diese Ausgänge:

I am defined in A 
I am defined in B 
I am defined in B 

Als allgemeine Regel gilt, wenn, würde ich diese Situation vermeiden und in den Modulen eine der Methoden umbenennen, wenn Sie sind in der Lage; obwohl du manchmal aus irgendeinem Grund nicht in der Lage bist.

0

Wenn es nur für a1 ist, dann sollte diese Arbeit:

class Sample 
    include A 
    def a1 
    self.class.a1 
    end 
end 

Wenn Sie es für alle Methoden benötigen, können Sie versuchen, die NoMethodError mit einem Sendebefehl Beschäftige für die Klasse, aber das ist in der Regel viel des Guten .

+1

Dies funktioniert nicht mit 'include' - Sie müssten stattdessen' extend'. –

Verwandte Themen