From: dblack@... Date: 2007-01-15T14:19:43+09:00 Subject: Re: inheritance concept in ruby Hi -- On Mon, 15 Jan 2007, Helder Ribeiro wrote: > Gregory Brown wrote: >> On 1/12/07, Helder Ribeiro 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)