In Ruby sind Mixins nicht mehrfach vererbbar, weil das Kombinieren von Mixin-Methoden eine einmalige Sache ist. Das wäre kein so großes Problem, außer dass die Module und Klassen von Ruby offen für Änderungen sind. Das heißt, wenn du ein Modul in deine Klasse mixinst und dann eine Methode zu dem Modul hinzufügst, wird die Methode wird nicht für Ihre Klasse zur Verfügung stehen, während es bei umgekehrter Reihenfolge der Fall wäre.
Das ist so, als würde man eine Eistüte bestellen. Wenn Sie Schokoladenstreusel und Toffee-Stückchen als Zutaten wählen und mit Ihrer Eiswaffel weggehen, ändert sich die Art der Eiswaffel nicht, wenn jemand in der Eisdiele bunte Streusel in den Behälter mit den Schokoladenstreuseln gibt. Ihre Klasse, die Eistüte, wird nicht verändert, wenn das Mixin-Modul, der Behälter mit Streuseln, verändert wird. Die nächste Person, die das Mixin-Modul verwendet, wird die Änderungen sehen.
Wenn Sie include
ein Modul in Ruby, ruft es Module#append_features
auf dieses Modul, die eine Kopie der Methoden dieses Moduls einmalig in den Includer einfügen.
Mehrfachvererbung ist, so wie ich es verstehe, eher eine Art Delegation. Wenn Ihre Klasse nicht weiß, wie sie etwas tun soll, fragt sie ihre Eltern. In einer Open-Class-Umgebung können die Eltern einer Klasse geändert worden sein, nachdem die Klasse erstellt wurde.
Es ist wie eine RL-Eltern-Kind-Beziehung. Deine Mutter hat vielleicht erst nach deiner Geburt gelernt zu jonglieren, aber wenn dich jemand darum bittet und du sie bittest, dir entweder zu zeigen, wie es geht (es zu kopieren, wenn du es brauchst) oder es für dich zu tun (reine Delegation), dann ist sie zu diesem Zeitpunkt dazu in der Lage, auch wenn du vor ihrer Fähigkeit zu jonglieren erschaffen wurdest.
Es ist möglich, ein Ruby-Modul 'include' so zu modifizieren, dass es sich eher wie Mehrfachvererbung verhält, indem man die Module#append_features
um eine Liste der Einbindungen zu führen und sie dann mit der Option method_added
Callback, aber das wäre eine große Abweichung vom Standard-Ruby und könnte zu großen Problemen bei der Arbeit mit anderem Code führen. Es könnte besser sein, einen Module#inherit
Methode, die die include
und auch die Delegation.
Ein Beispiel aus der Praxis, Enumerable
ist großartig. Wenn Sie definieren #each
und umfassen Enumerable
in Ihrer Klasse, dann haben Sie Zugriff auf eine ganze Reihe von Iteratoren, ohne dass Sie jeden einzelnen programmieren müssen.