Hi --

On Mon, 15 Jan 2007, Helder Ribeiro wrote:

> Gregory Brown wrote:
>> On 1/12/07, Helder Ribeiro <helder / gmail.com> wrote:
>>
>> (...) the issue is rarely with immediate dependencies, but dependency chains.
>>
>> I.e., with mixins,
>>
>> If I have A->B->C and C mixes in D, then E
>>
>> the lookup is C,E,D,B,A
>>
>> which logically is quick intuitive if you think about it.
>>
>> If I have A->B->C
>>
>> and  ?->D->C
>>
>> and
>>
>> ?->E->C
>>
>> Those two question marks represent two independent dependency chains
>> that you cannot be sure what they implement without knowing the
>> ancestors of each.
>
> That's true. It made me think of one thing though. The PickAxe, at
> least in that part I quoted, is silent about lookup order when mixed-in
> modules include modules. If you extend the reasoning, though, you can
> say that when a method call is made inside a class method, Ruby first
> checks for methods in that class, then in the modules it includes (so
> far nothing new) *and*, inside those modules, first for methods they
> implement themselves, and then for methods defined in modules mixed
> into them.

I'm not sure you really mean class method here.  What you're saying is
true of any time you send a message to an object -- that is, it looks
in its class, then the modules, etc.

> So how would this be different from the scenario you suggested with
> multiple inheritance? You can get an exactly analog problem, where the
> conflict might lie not in immediate dependencies, but in dependency
> chains. A->B->C can be the class hierarchy while ?->D->C and ?->E->C
> are module hierarchies.
>
> I didn't understand what you meant by "you cannot be sure what they
> implement without knowing the ancestors of each". Isn't that true even
> for A->B->C alone? You can't know what C implements unless you know B
> and C.
>
> And if the problem is only lookup order, separating class hierarchy
> from module hierarchy makes it easier only in the case where you have
> *one* class hierarchy (A->B->C) and *one* module hierarchy (F->D->C),
> because it is given that you choose first from the class hierarchy. For
> cases of 3+ you still have the same problems, right?

No, the lookup order principle still keeps it uniform.  It's useful to
think of it from the object's point of view.  You send a message to an
object, and it goes on a search for a method with a corresponding
name.  This search always takes place along an unambiguous, one-track
path.  The object doesn't see trees or forks in the road.

It's all based on order of inclusion, but I don't think that's an
arbitrary choice.  It's very much in keeping with the dynamic nature
of Ruby objects.  In fact, it *is* the dynamic nature of Ruby
objects; the singleton classes that allow for per-object behavior are
part of this system too.

There's still the possibility of name collision with mixins, but there
are (to my knowledge) no special cases, no need for tie-breaking rules
-- because the rules that are there in the first place make a tie
impossible.  Dealing with things like name collision is reduced
entirely to a function of knowing what's in the source code.  You need
to know whether a module you're including is going to occlude a method
further up the chain; but the rules that determine this are the same
as the rules that are in operation all along.

> And yet, this is a problem only when there is name collision which, as
> you said, is a small case and mostly due to code smell or unavoidable
> complexity.
>
> What I don't see is what exactly having separate class/module
> hierarchies buys you. You ensure a simple tree structure for the class
> inheritance graph, but you (apparently) don't have that for the module
> graph and they are both connected. Doesn't that blow the idea of tree
> for the former?

Maybe, but in the end it's not really a tree model; it's a path model.
When you include modules in classes, you're inserting them in the
method look-up path of instances of those classes.

> The only thing holding me from saying "it's a tree, *connected* to a
> general network, thus it's all a big network" is that the connection
> seems to be unidirectional (modules can't have classes 'mixed in' or
> inherit from them, I suppose). Is there some theoretical result that
> bases itself on this (or some other thing, I dunno) to say that there
> is a clear distinction between the M.I. model and the "tree +
> pan-inheritance-modules"?
>
> Furthermore, if both models are almost (or perhaps completely)
> equivalent *and* the only problem is with the limited case of name
> collision and that can be solved with lookup rules, where is the source
> of contention? Why would people favor one over the other?

The thing I like about modules is that I find the model a suggestive
way of thinking about domain modeling.  I like having both a noun-like
thing (classes) and an adjective-like thing (modules).  Then again,
all of this is purely in the context of Ruby; I don't inherently like
one or the other more.


David

-- 
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
    (See what readers are saying!  http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)