Will Ruby ever support multiple inheritance through classes instead of
modules? This is good since it won’t need modification of existing
classes, and/or converting them to modules or class-module pairs before
they are inherited by a new subclass with the use of include when we
reuse them.
class StableClassA
puts :A
end
class StableClassB
puts :B
end
class Inheritor < A, B # won’t work
puts :A
puts :B
end
To make things work:
module StableModuleA
puts :A
end
class StableClassA
include StableModuleA
end
module StableModuleB
puts :B
end
class StableClassB
include StableModuleB
end
class Inheritor
include StableModuleA
include StableModuleB
puts :I
end
Thanks for the reply. The information is adequate. It’s quite
disappointing though since because of that we tend to use class-module
pair format just to make class ready for multiple-inheritance by mixins
through its module; or else we always had to rewrite an existing class
or transfer its contents to a module or the inheriting class itself
every time we make use of the features.
I believe MI is not that evil and its potential is the one that’s more
to consider or look upon. Some languages also had their ways with
dealing with those problems: Multiple inheritance - Wikipedia.
I honestly think that Ruby would have been more enjoyable if it had
supported pure multiple inheritance.
Even though other languages handle multiple inheritance without any
problems they each handle it in different ways which can lead to subtle
bugs when moving from one language to another. Some languages have even
changed how they handle multiple inheritance between versions (Python
springs to mind here, multiple inheritance got ‘clarified’ at one point
or so my memory tells me).
Good points but think they’re really not that essential, especially if
it’s only about one language and just the use of it.
There is only one way to do single inheritance and this is a good thing.
Considering the capabilities of multiple inheritance and some situations
where single inheritance don’t apply and needs workarounds - like when
you make a class that needs to inherits a class from an external library
but also needs to inherit its natural parent class whereas you had no
choice but to just include the contents of the natural parent class to
it - I believe that’s not always true.
Coming from languages that allow for multiple inheritance I must say I
have yet to encounter a situation where I have said “this would be so much
easier with multiple inheritance”
Perhaps but please consider the example situations I gave. I doubt that
solutions could always be done without redundancy either by code or by
work while not sacrificing consistency among classes and not using
workarounds.
Even though other languages handle multiple inheritance without any
problems they each handle it in different ways which can lead to subtle
bugs when moving from one language to another. Some languages have even
changed how they handle multiple inheritance between versions (Python
springs to mind here, multiple inheritance got ‘clarified’ at one point
or so my memory tells me). There is only one way to do single
inheritance
and this is a good thing.
Coming from languages that allow for multiple inheritance I must say I
have
yet to encounter a situation where I have said “this would be so much
easier with multiple inheritance”
Well the example you gave at the head of this thread is pretty
meaningless.
It is always possible to create a convoluted problem that is hard to
implement in any language. My experience in not finding a need for
multiple
inheritance comes from writing code that people will pay for. No one has
presented my with a genuine problem (as opposed to a puzzle problem)
where
single inheritance was inadequate. I’m not saying that they don’t exist
but
as problems go I have yet to encounter one.
Ok then lets return to your puzzle problem. Given the first example that
doesn’t work. Well done you wrote some code that is invalid Ruby, guess
what, you can do that in any language even if it has multiple
inheritance.
Now your second example, why did you write it that way? There is no need
for StableClassA or StableClassB. Throw them away and nothing changes as
Inheritor does not inherit from either of them. Here’s the code that
works
the same, it is written as any Ruby programmer would write it.
module StableModuleA
puts :A
end
module StableModuleB
puts :B
end
class Inheritor
include StableModuleA
include StableModuleB
puts :I
end
Notice how it looks like the first (broken) example but with modules not
classes. Notice also how it actually works.
Can you now explain what advantages multiple inheritance is supposed to
have over the code given here?
This is why puzzle problems suck. Just give a real problem that is
better
solved by multiple inheritance and you will have proven your point.
Well the example you gave at the head of this thread is pretty
meaningless.
Depends on one’s principles. Also, perhaps it’s all because I just
wanted to give a brief example. I could give real situation examples but
I find that unnecessary. Also please try to give attention and not evade
the details I give at least for the sake of keeping this thread
discussion shorter.
It is always possible to create a convoluted problem that is hard to
implement in any language. My experience in not finding a need for
multiple inheritance comes from writing code that people will pay for. No one
has presented my with a genuine problem (as opposed to a puzzle problem)
where single inheritance was inadequate.
It’s not always about as-long-as-it-works theories. Using workarounds is
not that bad, probably, but sometimes they’re too fixed, too hard to
apply, or too heavy by size that it could have been easier if one
feature was available.
It also depends on how you love the design of your craft. Not all
projects are made for the sake of monetary profit. Not that I’m saying
it’s all about craftiness.
Simplicity though safe doesn’t always yield simple results. Sometimes
due to its limits a more complex output is made.
Turns out you really don’t have the idea. I’m guessing
we’ll be going through the details bit by bit before you fully
understand what I mean.
Provide working code in the language of your choice that demonstrates a
problem that is better served by multiple inheritance than single
inheritance and you will have proven your point.
Ok then lets return to your puzzle problem. Given the first example that
doesn’t work. Well done you wrote some code that is invalid Ruby, guess
what, you can do that in any language even if it has multiple
inheritance.
Yeah I noticed that I didn’t place them in methods and directly used
puts instructions. It’s pretty obvious. So what about it?
Now your second example, why did you write it that way? There is no need
for StableClassA or StableClassB. Throw them away and nothing changes as
Inheritor does not inherit from either of them. Here’s the code that
works
the same, it is written as any Ruby programmer would write it.
Sigh. I was hoping you had understand the essence of this post already.
StableClassA and StableClassB is meant to be used as standalone and
working classes as well. They’re not just inherited as virtual, abstract
or incomplete classes.
module StableModuleA
puts :A
end
module StableModuleB
puts :B
end
class Inheritor
include StableModuleA
include StableModuleB
puts :I
end
Notice how it looks like the first (broken) example but with modules not
classes. Notice also how it actually works.
Can you now explain what advantages multiple inheritance is supposed to
have over the code given here?
This is why puzzle problems suck. Just give a real problem that is
better
solved by multiple inheritance and you will have proven your point.
Try to reconsider things again from my reply which is meant to be
obvious actually. Turns out you really don’t have the idea. I’m guessing
we’ll be going through the details bit by bit before you fully
understand what I mean.
Provide working code in the language of your choice that demonstrates a
problem that is better served by multiple inheritance than single
inheritance and you will have proven your point.
I believe I had explained enough. If it’s about examples there are many
around the web. If one is interested to know more about the advantages
of having multiple inheritance there certainly are many around the web.
It’s not that I can’t prove anything. I already encountered two
situations twice and both were related to inheriting an external class
where one of the other parent class was already a working class - that
which could have solved things simpler and easier if MI was possible.
Come to think of it I could actually give you a summary of those
classes.
And this time this was not possible. I now have to decide whether I have
to merge all codes from Updater to DaemonUpdater to make it work with
ServiceUpdater or use another Class to Inherit Daemon that would control
ServiceUpdater which would really be a hassle design-wise. No matter how
you look at multi-inheritance would be the easiest form. Other
variations would be just workarounds or redundant forms.
Now please reconsider again if you’re going to question if my analogy
with respect to the matter wasn’t really that deep that there could have
been something I missed for you to question me again. This is also just
an example. An enough proof of concept as I could see it.
In message “Re: Support for multiple Inheritance by classes”
on Mon, 5 Nov 2012 01:55:36 +0900, Ross K. [email protected] writes:
|Updater
|OneTimeUpdater < Updater
|DaemonUpdater < Updater
|
|Then the utility was stable. After some time I decided to port it.
|
|ServiceUpdater < DaemonUpdater, Daemon (External Class)
As a general principles, multiple inheritance can be replaced by
modules+mix-in.
|And this time this was not possible. I now have to decide whether I have
|to merge all codes from Updater to DaemonUpdater to make it work with
|ServiceUpdater or use another Class to Inherit Daemon that would control
|ServiceUpdater which would really be a hassle design-wise. No matter how
|you look at multi-inheritance would be the easiest form. Other
|variations would be just workarounds or redundant forms.
It might be “work around”. But you have to pay the price of
inheritance graph complexity and resolving conflicts anyway.
Do you fully understand C3 algorithm that CLOS uses to resolve
multiple inheritance priority order. I don’t. That’s one of the
reason I didn’t put multiple inheritance in to Ruby.
So, you have options. a) Use mix-ins, compromising “work around”.
b) just go to a language with multiple inheritance.
Provide working code in the language of your choice that demonstrates a
problem that is better served by multiple inheritance than single
inheritance and you will have proven your point.
I believe I had explained enough. If it’s about examples there are many
around the web.
I have googled and cannot find an example of a problem that is better
served by multiple inheritance than single inheritance. If you know of
one
then I would be grateful if you could provide the url.
If one is interested to know more about the advantages
of having multiple inheritance there certainly are many around the web.
Now you are avoiding the question. I am well aware of the advantages of
multiple inheritance, that is not what I asked. What I asked for was
“a problem that is better served by multiple inheritance than
single inheritance”. You have not provided one and therefore any hand
wavy arguments you put forward only serve to convince me that you do not
know of even a single instance.
It’s not that I can’t prove anything.
Good, then show me the code.
Come to think of it I could actually give you a summary of those
classes.
Again with the hand waving. Without seeing the code I am unable to see
how
this could be refactored to make it easily implemented with single
inheritance. Likewise I cannot see how difficult it might be and go “oh
he’s right, this would be easier with multiple inheritance”.
Of course I could just take you word for it … never gonna happen
Thanks for the reply. The information is adequate. It’s quite
disappointing though since because of that we tend to use class-module
pair format just to make class ready for multiple-inheritance by mixins
through its module; or else we always had to rewrite an existing class
or transfer its contents to a module or the inheriting class itself
every time we make use of the features.
What you’re basically saying here is we can get most of the properties
of
multiple inheritance from mixins. That’s good!
MI vs. mixins is a philosophical debate. Mixins are a much simpler, more
easy-to-reason-about model than true multiple inheritance, IMO. MI
brings
with it all sorts of odd corner cases, such as the Diamond Inheritance
Problem:
So what you view as a weakness I see as a strength.
I honestly think that Ruby would have been more enjoyable if it had
supported pure multiple inheritance.
If you really want a Ruby-like language with multiple inheritance, might
I
suggest Python?
Multiple Inheritance is the GOTO statement of object oriented
programming – sort of a caveat emptor to people new to the paradigm
coming from a procedural language background.
Module/mix-in would work as far as conceptually. If it’s a daemon, as
the so called example used, a system level service. The paradigm
changes. In UNIX not everything is an object. Formally taught to
sysadmins that everything is a file which really really means
everything is a stream of bytes( i.e. C Programming and system
kernel/shell)… This is why Kernel in ruby is a module and not a
class.
I can’t think of one reason why multiple inheritance would be useful
for daemon process. Updating based on changes can be accomplished
through creating wrappers to the signals much the same way rc.d/init.d
is. Inside ruby you have access to message passing much the same as
you would expect from any object oriented language.
Ultimately there is nothing wrong with wanting a feature. Consider it
a challenge to work within the context of the language or hack up your
own dsl. MI is not the panacea that early oops language designers
thought it would be. There most certainly is a better way to deal with
various problems and solutions.
Also it’s not a “work around” to use Mix-in Modules as the op
suggested. It’s actually the preferred and correct way i.e. the Ruby
way. Hit up a couple non object oriented languages and move data back
and forth there. That is the only way to gain enough insight to know
what is a “work around” vs the concept of “working with”. The
limitations are not with the ruby language or interpreter. It’s with
the users who superimposes such limitations upon themselves.
For one reason or another this thread reminded me of the Execution In
Kingdom of Nouns
Thank you everyone for giving their attention and thoughts to the
thread, especially Yukihiro-san. It’s truly an honor.
I believe my question has been answered already and discussing
advantages and disadvantages of multi-inheritance over
single-inheritance with aid of modules is another thing.
Hearing everyone’s thoughts especially the master, I think I would just
accept and respect Ruby the way it is, save that someday I might make a
personal extension of it if I’m able, well not really.
Thanks again.
I actually imagined this:
class Ruby
inherit Multiple
inherit Inheritance
end
If you have ever used a Ruby module as a mixin then you’ve used multiple
inheritance. Period. There’s no wiggle room. What is a mixin in Ruby is
part, only part, of what a general multiple inheritance mechanism
provides in other languages.
And I’ll bet that most of you who have used mixins thought they worked
out pretty well.
So. You’ve used multiple inheritance and thought it was a good thing.
WHY the near universal contempt for multiple inheritance? What’s up?
or transfer its contents to a module or the inheriting class itself
every time we make use of the features.
If you notice you do this regularly you are probably doing something
wrong
with regard to Ruby’s OOP. It looks as if you want to carry over your
inheritance scheme from language X (C++, Eiffel…). If something is an
entity (class) and a set of functionality used in various places
(module)
at the same time then maybe you do not separate the two clear enough.
For
example, you might notice that your reported 1:1 relationship between
class
and module should rather be a 1:4 relationship (i.e. an entity being
built
from various functionalities). Or maybe you are using inheritance where
you should rather use composition. All that could of course be
discussed
much better with a concrete example of your code…
I believe MI is not that evil and its potential is the one that’s more
to consider or look upon. Some languages also had their ways with
dealing with those problems: Multiple inheritance - Wikipedia.
I honestly think that Ruby would have been more enjoyable if it had
supported pure multiple inheritance.
For me absence of class MI does not take anything away from the fun and
I
can’t imagine how it could be more fun with class MI. I tend to believe
though that inheritance is generally overrated. For me encapsulation is
a
much more important concept in OOP than inheritance.