Hi Helder, sorry it took me a while to get back to these questions,
but I've done what I could to answer them below.
I can't remember where in the thread you talked about a class
hierarchy vs. a mixin hierarchy.
The thing is, though it is likely you'll end up on a long chain of
subclasses in a complex system, it's unlikely you'll run into a deeply
nested set of modules. Even when you do, these modules will typically
implement things that are orthogonal from each other, so you can still
look at any given module as a distinct unit living outside of the
class heirarchy.
Once mixed in, it more or less becomes part of the class definition,
and the call order is pretty intuitive in practice. The same cannot
be said for Multiple Inheritance unless the system is designed with
much care. That's the core of the reasoning behind modules as far I
can tell, and the responses that follow have that in mind...
Yes, i meant any method call. But I haven't found this lookup order
stated in its full anywhere else. The part after the "*and*" is what I
inferred from what the PickAxe says about the other cases (the quote is
in this thread somewhere).
Perhaps we need to document this better. I'm not sure where the best
place would be, though.
But this is an artificial difference, because you can define a lookup
order to solve this conflict without the need for Modules. So the
question is
"since Ruby already has a well-defined lookup order that takes care of
conflicts in class/module hierarchies, couldn't you have a similarly
well-defined lookup order for Multiple Inheritance and do away with
Modules altogether?"
Probably. But the question is, why would you want to do this? I
suppose what would be important to know is whether this interest in
the system is of theoretical or practical grounds for you. If it is
of theoretical grounds, these are all valid questions, but I do think
they'd end up somewhere around the 'this is how matz implemented them,
so unless something Really Wrong with them can be shown, they're here
to stay' conclusion. It is good to talk about these things because it
lets us understand better how they work, but I'm not sure that I've
seen many cases *for* MI in ruby. Since we seem to be getting along
fine without them, the whole "If it ain't broke, don't fix it" adage
applies.
If your interest in this is based on a practical modeling issue, I
think it'd be better for you to describe the model that you are
dealing with so we can help you think of ways to express it cleanly in
Ruby. Perhaps seeing the way modules are used in practice would help
clear some of the fuzzy areas up for you.
Don't understand what you're saying. There is, indeed, no need for
tie-breaking rules if you have lookup order rules (i'm assuming those
are what you mean by "the rules that are there"). It happens that they
are the same, though, you're just giving them different names.
Tie breaking rules are necessary when you end up with cycles in the graph.
The MRO for Python 2.3 is pretty straightforward, mostly because it
fails if this occurs (preventing the need for complex tie breaking
rules).
http://www.python.org/download/releases/2.3/mro/
With mixins however, there is no situation where this would occur,
which is one of it's strengths.
Actually, multiple inheritence is meant more-or-less to solve the same
problem, to unify orthogonal concerns. To me it's just a cleaner
system to accomplish the same basic goal, while providing a little bit
more protection against shooting yourself in the foot.
However, the same problems can indeed arise from both, I just think
the mixin model puts you in a mindframe that discourages that. (One
you get used to how it works)
So the difference is only in the way you think about those two things
(classes and modules)? Or do they have some difference in their
inheritance behavior that makes you think multiple inheritance would be
unsuitable for what you do (I know nothing about domain modeling)?
This is mostly a style thing.
If you think of some module names, you get things like Comparable and
Enumerable.
Now let's put that in the context of use with classes.
Some object is an Array. That Array is Enumerable.
Some object is a Fixnum. That Fixnum is Comparable.
So just like using any concept to organize your code, on it's own,
there is little technical difference.
But it is very powerful when you use the concepts right. You say,
hmm... I'm looking at a relationship in which this chunk of code
describes the kinds of things you can do with an object if it meets
certain criteria, that sounds like a module would make sense. Or,
this object embodies something rather concrete with unique behaviors,
perhaps a class would be appropriate.
Sometimes this changes as you go through your development process.
Sometimes you realize you only needed a module and you used a class.
Or sometimes the opposite happens. So it's not like Ruby is forcing
your hand to do one or the other. The relative similarities between
the two make it somewhat easy to refactor from one to another without
changing much.