开发者

How is Ruby module inclusion not really 'multiple inheritance' and how does the Ruby style avoid the problems associated with multiple inheritance?

Matz supposedly said "mixins could do almost everything multiple inheritance do, without the associated drawbacks" (Matz words)."

First of all, why is Ruby module inclusion not 'multiple inheritance' ? It seems to me there is very little difference betw开发者_如何学JAVAeen modules and classes. The fact you cannot instantiate a module is irrelevant when it is used as a superclass.

I also know that successive module inclusion forms a single inheritance chain (not tree) extending upwards from the class. But this, to me, is not sufficient to distinguish it from 'multiple inheritance' as the Python multiple inheritance system also "linearizes" the superclass chain (using the C3 algorithm) it's just that Ruby 'linearizing' process is significantly simpler.

So what exactly distinguishes Ruby module mixins from multiple inheritance in say a language like Python? And why don't the arguments behind the Python adoption of the c3 MRO algorithm apply to Ruby? And if they do apply - why did Ruby decide not to adopt this algorithm ?

thanks


With MI, lots of the issues that arise can be trimmed down to implementation details; you can't just talk about "Multiple inheritance" in general, without talking specifics. So I'll be assuming that you mean "C++ multiple inheritance" when you say "multiple inheritance".

The most common problem with Multiple inheritance is the Diamond Problem. If several superclasses on the same level define the same method, how do you know which method is invoked on the subclass?

With modules, this problem is easily answered - the last included module always "wins". You can't include several modules "simultaneously", as you can do with classes in C++. So this problem never arises.

The fact you cannot instantiate a module is irrelevant when it is used as a superclass

I respectfully disagree.

First, modules are never "used as superclasses" in ruby; only superclasses are.

Second, with multiple inheritance, knowing exactly in what order the constructors (& destructors!) are called is not a trivial matter. The fact that ruby modules don't allow instantiation suppresses that problem altogether.


Adding this on Mladen's behalf as an actual answer, because I found it very helpful, and I'm guessing answers get indexed better for whatever crazy things SO does with it.

Here is a nice article on that matter, see if it answers your question: http://artima.com/weblogs/viewpost.jsp?thread=246488 – Mladen Jablanović Oct 28 '10 at 18:23


Check out the book "Metaprogramming Ruby" from the Pragmatic Press. It contains a very detailed explanation of this, in a manner that is very easy to read and understand. http://pragprog.com/titles/ppmetr/metaprogramming-ruby

i can't answer mot of your questions because i don't know python. but the basics of why it's not multiple inheritance is that ruby injects the module into the inheritance chain when the module is included or a class is extended by a module.

class Foo
  include Bar
end

module Bar
end

foo = Foo.new

this produces an inheritance chain where foo is an instance of Foo and Foo inherits from Bar.

it's a bit more tricky than just that, and there are rules for the order in which the inheritance injection occurs. the book i referenced explains it very well.


Most important in ruby is you overwrite previous definitions of data/functions with every included module.

So it is bad as every new module should theoretical take care of giving access to previous code which gets overwritten.

So example code to write new module is (logically):

old_function = fun
fun = define_new_function
  do_you_staff
  call old_function

You do not have to use old function, although in most cases it's useful but sometimes it is easier to rewrite the whole code.

Each included module will build chain of overwritten methods, so there will be no problems with multiple inheritance but order of including modules gets more important.

This method is also called monkey patching - term widely used in Ruby on Rails.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜