From: "David A. Black" Date: 2005-04-10T06:13:53+09:00 Subject: Re: method search rule in 2.0? Hi -- On Sun, 10 Apr 2005, Paul Hanchett wrote: > David A. Black wrote: >> Hi -- >> >> On Sat, 9 Apr 2005, David Garamond wrote: >> >>> I read: >>> >>> >>> http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=Ruby2.0MethodSearchRuleEnglish >>> >>> and was feeling disturbed about this new Ruby2 behaviour. >>> >>> class C >>> def process >>> # ... >>> util >>> end >>> >>> def util >>> # ... >>> end >>> end >>> >>> class CC < C >>> def util >>> # ... >>> end >>> end >>> >>> CC.new.process # C#process expects C#util, >>> # but calls CC#util >>> >>> Why is this a problem? Isn't it what people expect in OO? I'm not >>> an OO expert, but isn't this one of the supposedly unique >>> feature/benefit of OO: allowing old code to call new code. I >>> believe it's called polymorphism? >>> >>> Now Ruby2 wants to change so that 'util' in C method calls C#util >>> and 'self.util' calls CC#util. I very much prefer 'self.util' to be >>> the one that calls C#util (and I don't think I'll ever use it a >>> lot). The latter is backwards compatible and how virtually all >>> other languages behave. >> >> >> I agree that the non-special case should be what it is now, and the >> case where you don't want overriding should be the one that requires >> something extra. But I don't think it should be based on >> overloading >> "self" (and I believe having "self" refer to the class context, >> rather >> than the object, is a kind of overloading). If this mechanism is >> really necessary, I would rather see: >> >> class C >> def process >> # ... >> C#util >> end >> end >> >> which is, I think, a more direct way of saying: protect this call >> from >> overriding in subclasses. (Yes, everybody, I do know that this is >> comment syntax and would require a parser change :-) > > If I was writing class C, I would be surprised when CC#util got > called, but that is exactly the OO behavior you want sometimes. I > think both the naked call to util and self.util should be relative to > the /instantiated/ object. I agree. That's why I don't like the proposed change to "self". > If I really want to call C#util, why not say C::util? It seems like > anything else has compatibility problems... C::util is a class method call, but what we're talking about here pertains to instance methods. The idea of C#util is not to call C::util, but to call util on the instatiated object -- constraining that call so that it is the #util defined in class C, not class CC. class C def x puts "I'm the #x from C" end def y x # call the most recently defined #x at the time of the call end def z C#x # call the x defined in C, no matter what end end class CC < C def x puts "I'm the #x from CC" end end CC.new.y # I'm the #x from CC CC.new.z # I'm the #x from C Note that having a CC object "call the x defined in C" is different from saying "Call the class method C.x" (which doesn't exist at all). David -- David A. Black dblack@wobblini.net