From: David Flanagan Date: 2007-06-14T04:29:04+09:00 Subject: Re: new method dispatch rule (matz' proposal) This is a late response to the very long thread that started back in January with this message: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9996 As I understand it, the problem Matz is seeking to address is that private methods are inherited by and may be overridden by subclasses. This means that a subclass writer can inadvertently alter the behavior of its superclass simply by defining a method that has the same name as an internal helper method of the superclass. The only way to defend against this is for subclass writers to be familiar with the internal implementation of the superclass. Matz's proposal was to resolve this problem by altering the method resolution algorithm. If I understand correctly, the problems were: 1) It was kind of complicated 2) The method lookup algorithm depended on whether a method was called functionally without an object prefix or in OO form with an object prefix. (That is called as foo() or o.foo()) 3) There were backward compatibility issues Part of the discussion was about the question of whether to alter the semantics of private methods, or add a new "local" or "personal" visibility level for methods that were truely local to the defining class and could not be inherited or overridden. With all that as review, here are my thoughts on the matter. 1) It is reasonable to expect private methods (or local methods if we call them that) to be looked up and dispatched differently than non-private methods. 2) The problem, though, is that since Ruby is a dynamic language, the interpreter can't tell whether a method is private or not until it has looked it up. 3) Therefore, solutions like Matz's proposal depend on the method invocation syntax (functional style versus object-oriented style) to determine which method lookup algorithm is to be used. This leads to the confusing and hard-to-justify situation in which the invocation "foo" might do something different than the invocation "self.foo". I propose, therefore, that some new syntax be introduced (avoiding backward incompatibility) either for making local method names obviously different from other method names. Or that a new method invocation syntax be introduced and that this new syntax be used when we want to invoke a local method defined in (or inherited by) the caller without considering any methods defined further down the class hierarchy. I don't grok parse.y well enough to know whether any syntax I would propose would actually result in an unambiguous grammar, but my suggestion is that local methods have an @ prefix just like instance variables do. Then the interpreter knows from the name of the method that it is to be dispatched differently. In fact, I might actually go further than this and propose that local methods are not actually methods, but are syntactic sugar for lambdas. In Ruby 1.8, we can write code like this: class Test def initialize(greeting) @greeting = greeting @greeter = lambda { |x| puts "#@greeting #{x}" } end def greet(x) @greeter[x] end end t = Test.new("hello") t.greet("world") In this code, the instance variable @greeter refers to a local function that is completely hidden from subclasses and cannot be altered. Perhaps Ruby 1.9 could take this idiom and add syntax sugar to make the definition and invocation of local functions more like the definition and invocation of regular methods. David Flanagan