From: Paul Brannan Date: 2001-10-07T13:42:38+09:00 Subject: [ruby-talk:22182] Re: Ruby and multiple inheritance Mathieu Bouchard wrote: > Say there's a diamond relationship with B with classic multiple inheritance there is no way that a method in C can > call a method in B. with Ruby's model, you do this by calling super. Here's an example that illustrates our discussion on #ruby-lang. Compare the following C++ program: #include struct Base { virtual void foo() { std::cout << "Base" << std::endl; } }; struct Left : virtual public Base { virtual void foo() { Base::foo(); std::cout << "Right" << std::endl; } }; struct Right : virtual public Base { virtual void foo() { Base::foo(); std::cout << "Right" << std::endl; } }; struct Derived : virtual public Left, virtual public Right { virtual void foo() { Base::foo(); // C++ does not have anything like Ruby's super() std::cout << "Derived" << std::endl; } }; int main() { Derived d; d.foo(); } with the following Ruby program: module Base def foo puts "Base" end end module Left include Base def foo super puts "Left" end end module Right include Base def foo super puts "Right" end end class Derived include Left include Right def foo super # How can I specify that I want to call Base's foo()? puts "Derived" end end d = Derived.new d.foo In the C++ example, Left::foo and Right::foo both call Base::foo. In the Ruby example, Right::foo calls Left::foo, and Left::foo calls Base::foo. That's not immediately clear from what's written, though; someone who doesn't know about how Ruby's inheritance works might expect Left::foo and Right::foo to call Base::foo, as in C++. The difference is that in C++, the relationship looks like: Base / \ Left Right \ / Derived While in Ruby, it looks like: Base <--- Left <--- Right <--- Derived >>there's no well-defined way to initialize instance data in a mixin (with >>inerhitance in Ruby, you initialize the base class with super()). > > there _is_ a well-defined way to initialize mixin data, as > you can deduce from the message you replied to, and from what I've said > above. Good point. I had not considered adding an initialize() method to a mixin. However, what do I do if I want to mixin two modules, and each module has an initialize method that takes a different parameter? There is no good way to initialize both mixins in this case. >>I've found that not thinking of mixins as a replacement for MI has been >>beneficial to my health. > > MI is not a replacement for Ruby's model. Agreed. They are separate beasts with separate functions. Paul