Method search rule in 2.0?

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.

Regards,
dave

David Garamond wrote:

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 totally agree with you.

I think a better way of solving this problem is using private methods which are only part of the class for which they are defined. If a subclass defines a method (private, protected or public) with the same name as the private method in the superclass then all calls to the private method made by methods in the superclass call the private method in the super class. All methods calls on the method in the subclass call the method defined there. Public or protected methods defined in superclasses can be overriden in subclasses and when they are called from the superclass the overriden method will be called. I believe this is the way Java and C++ (among others) work.

Regards,

Peter

Hi --

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 :slight_smile:

David

···

On Sat, 9 Apr 2005, David Garamond wrote:

--
David A. Black
dblack@wobblini.net

Ah, this is interesting. In the AOP work I've been doing, something
along these lines is a absolute must inorder to prevent method name
clashes and thus have fully reusable Aspects. My solution was to have
another scoping mechinism akin to public, private, protected, called
"local". It differs in that methods defined in the local scope are
always called locally in the context of that module, but not in the
context of any other. For instance:

  class C
    def x ; 1 ; end
  end

  class D
    def y ; x ; end
    local
    def x ; 2 ; end
  end

  d = D.new
  d.y #=> 2
  d.x #=> 1

T.

David Garamond <lists@zara.6.isreserved.com> writes:

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 would have to agree. As an OO programmer, the current behaviour is
what I would expect. And I'd go so far as to say that it's the
"correct" behaviour. When I call #util, I'm not "expecting" C#util, I'm
expecting the *right* #util to be called, where the "right" #util is
defined as the one that preserves the invariants of whatever class
self is a member of. An contrived example of why this is important:

class A

    ...

    def do_stuff
        data = get_some_data()
        store(data)
    end

    def store(data)
        @mydata << data
    end
end

class ThreadSafeA

    ...

    def store(data)
        @mutex.lock
        @mydata << data
        @mutex.unlock
    end
end

a = ThreadSafeA.new
a.do_stuff

In this case if the call to do_stuff resulted in a call to A#store, it
would violate the thread-safety invariant promised by ThreadSafeA.

Maybe not the best example, but it's a pattern which permeates OO
design. It's the Strategy pattern, really: a superclass defines some
broad, high-level methods which are implemented in terms of more
granular support methods; and then the implementation strategy is
defined by subclassing it and overriding the suport methods.

Actually, in my mind applying the principle of least astonishment
would lead to expecting store and self.store to have identical
behaviour. I would expect to have to use something like super.store
or A::store in order to specify that I want the superclass version of
store.

···

--
ABG

Silly me. I never read the orignal material. I just went back and did
so and now see that the local concept I brought up is really exactly
the kind of solution the author is looking for --at least according to
the stated problem.

The idea of directed method calls (i.e. C#x) is really a separate idea
--albeit related.

Interesting...
T.

http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=Ruby2.0MethodSearchRuleEnglish
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 want neither util() nor self.util() to call C's util directly, and if either change passes, then I *will* reconsider my five-year relationship with Ruby. I can't even begin to imagine the amount of code that this change would break anyway, so I can't imagine Matz making that change either.

  ,-o---------o---------o---------o-. ,----. |
  > The Diagram is the Program (TM) | | ,-o----------------------------o-.
  `-o-----------------------------o-' | | Mathieu Bouchard (Montréal QC) |

···

On Sat, 9 Apr 2005, David Garamond wrote:
    > >---' | http://artengine.ca/matju |
    > > `-o------------------------------'

As by the ruby of today, how you can do the above is:

    class C
      def process
        # ...
        C.instance_method(:util).bind(self).call
      end
    end

Now you will agree that it is not particularly convenient; but this is
how to do it... But. It's sooo long that you can't help remembering the
occasion if you use it.

And I don't remember doing it more that one or two times. That is, my
experience suggests that it's not a particularly frequent pattern. Which
means I agree with those who like the present state of the art.

Csaba

···

On 2005-04-09, David A. Black <dblack@wobblini.net> wrote:

   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 :slight_smile:

David A. Black a écrit :

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 :slight_smile:

David

  class C
   def process
    # ...
    C::util
   end
  end

equivalent to

  class C
   def process
    # ...
    self.C::util
   end
  end

equivalent to

  class C
   def process
    # ...
    self.(C::util)
   end
  end

···

--
Lionel Thiry

David A. Black wrote:

Hi --

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 :slight_smile:

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.

If I really want to call C#util, why not say C::util? It seems like anything else has compatibility problems...

Paul

···

On Sat, 9 Apr 2005, David Garamond wrote:

Avdi Grimm wrote:

Actually, in my mind applying the principle of least astonishment
would lead to expecting store and self.store to have identical
behaviour. I would expect to have to use something like super.store
or A::store in order to specify that I want the superclass version of
store.

I have to agree with you. While making a distinction around the use of
self.x verses x seems reasonable to some degree (after all they are
written differently), the old ambiguity of x= raises it's ugly head. To
refresh, x= would be interpreted as a local variable assignment and not
a method call, thus requiring the use of self.x= instead. B/c of this
x= and self.x= must remain equivalent.

But lets say we do adopt a differnt syntax as you suggest. Of the
options I think David's suggestion of M#x is the most obvious since
that's the standard way to refer to a method already. But even this has
problems in that it puts some limits on reusability. Consider:

  module M
    def x ; 1 ; end
    def y1 ; M#x ; end
    def y2 ; M#x ; end
    def y3 ; M#x ; end
    # etc.
  end

Perhaps originally it wasn't intended to be used otherwise, but if we
later wanted to create a variation of M with an altered #x, we'd then
have a problem b/c ordinary code like:

  class N
    include M
    def x ; 2 ; end
  end

  n = N.new
  n.y1 #=> 1
  n.y2 #=> 1
  n.y3 #=> 1

won't work. To overcome we'd actually have to redefine #y1, #y2, #y3
.... and so on. Not good. Of course Ruby has meta-programming techinques
that could be used to get around this, but who wants to dig even
further into complexity? That's why I think a localized namespace would
be preferable, as it is reasonably straightforward and would allow for
both contingencies.

T.

Hi --

David A. Black a écrit :

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 :slight_smile:

David

class C
def process
  # ...
  C::util

That's different; that's a class method.

end
end

equivalent to

class C
def process
  # ...
  self.C::util
end
end

equivalent to

class C
def process
  # ...
  self.(C::util)
end
end

These last two don't really fit the dot semantics, and if they're
alternatives to C::util, then they're dealing with a class method
anyway (rather than the issue of limiting the effect of overriding
instance methods).

My suggestion of C#util is based on the common use of # to mean
"instance method of the named class or module". It wouldn't require
redefinition of the dot notation, nor overloading 'self' to be a
boolean flag (as in the original proposal, where 'self' means both
"the default object" and "don't redirect this to an overridden version
of the method).

David

···

On Sun, 10 Apr 2005, Lionel Thiry wrote:

--
David A. Black
dblack@wobblini.net

Hi --

David A. Black wrote:

Hi --

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 :slight_smile:

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

···

On Sun, 10 Apr 2005, Paul Hanchett wrote:

On Sat, 9 Apr 2005, David Garamond wrote:

--
David A. Black
dblack@wobblini.net

Hi --

Avdi Grimm wrote:

Actually, in my mind applying the principle of least astonishment
would lead to expecting store and self.store to have identical
behaviour. I would expect to have to use something like super.store
or A::store in order to specify that I want the superclass version of
store.

I have to agree with you. While making a distinction around the use of
self.x verses x seems reasonable to some degree (after all they are
written differently), the old ambiguity of x= raises it's ugly head.

They're written differently, but the whole self.x = y thing is just
the price we pay for, in every other situation, being allowed to drop
'self' as the receiver. It keeps things simple and clean, overall
(and it's really not *that* ugly; it's just a receiver :slight_smile: So I
wouldn't want to look at that as a rationale for overloading it, which
would make it less simple.

To
refresh, x= would be interpreted as a local variable assignment and not
a method call, thus requiring the use of self.x= instead. B/c of this
x= and self.x= must remain equivalent.

But lets say we do adopt a differnt syntax as you suggest. Of the
options I think David's suggestion of M#x is the most obvious since
that's the standard way to refer to a method already. But even this has
problems in that it puts some limits on reusability. Consider:

module M
   def x ; 1 ; end
   def y1 ; M#x ; end
   def y2 ; M#x ; end
   def y3 ; M#x ; end
   # etc.
end

Perhaps originally it wasn't intended to be used otherwise, but if we
later wanted to create a variation of M with an altered #x, we'd then
have a problem b/c ordinary code like:

class N
   include M
   def x ; 2 ; end
end

n = N.new
n.y1 #=> 1
n.y2 #=> 1
n.y3 #=> 1

won't work. To overcome we'd actually have to redefine #y1, #y2, #y3
.... and so on. Not good.

But that's the whole purpose of the thing (whether it's M#x or self.x
or whatever) -- to constrain the nested method call (the call to #x
inside M#y1 etc.) and protect it from the redefinition of #x. I'm not
convinced of the merits of it (I continue to tend to think that anyone
subclassing a class should know the names of that class's methods, and
not accidentally override them), but the idea is specifically to
provide that protection.

David

···

On Tue, 12 Apr 2005, Trans wrote:

--
David A. Black
dblack@wobblini.net

David A. Black a écrit :

Hi --

David A. Black a �crit :

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 :slight_smile:

David

class C
def process
  # ...
  C::util

That's different; that's a class method.

In present ruby, yes, C::util is identical to C.util.

But I was thinking of "C::util" as an explicit namespace specification, not as a message sending to C object.

You talked about adding some "#" new operator could be inadequate as it is usually used for comments. I was just indicating "::" could do the job.

Sorry for my lack of clarity.

end
end

equivalent to

class C
def process
  # ...
  self.C::util
end
end

equivalent to

class C
def process
  # ...
  self.(C::util)
end
end

These last two don't really fit the dot semantics, and if they're
alternatives to C::util, then they're dealing with a class method
anyway (rather than the issue of limiting the effect of overriding
instance methods).

My suggestion of C#util is based on the common use of # to mean
"instance method of the named class or module". It wouldn't require
redefinition of the dot notation, nor overloading 'self' to be a
boolean flag (as in the original proposal, where 'self' means both
"the default object" and "don't redirect this to an overridden version
of the method).

And what is your opinion, now, if you take for granted that "::" semantic is redefined?

···

On Sun, 10 Apr 2005, Lionel Thiry wrote:

--
Lionel Thiry

David A. Black wrote:

   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

If you don't mind David, I think this is good example to show what I
mean by a local namespace too. The local namespace idea is sort like
the original idea (differentiating on using self or not) but remains
backward compatible.

  class C
    def x
      puts "I'm the #x from C"
    end
    local :x # localize x to C

    def y
      self.x # call the most recently defined #x
               # in this case using self forces a non-local call
    end

    def z
      x # call the x defined in C, b/c x is local
    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

Hope that makes my idea a bit clearer. This approach has an advantage
over notations like C#x also, in that modules can then be included into
a class' local space.

  module CM
    def x
      puts "I'm the #x from CM"
    end
  end

  class C
    include_local CM
    def x
      puts "I'm the #x from C"
    end
    def z
      x
    end
  end

  CC.new.x # I'm the #x from C
  CC.new.z # I'm the #x from CM

Note there isn't any name clash between the local and non-local x
methods (in fact that's the whole point) local methods are referenced
in there own namespace.

T.

David A. Black wrote:

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 if C#util is not defined as a with "def C.util ..." isn't it just a regular method? Or is C::util really a different sort of call to the class object?

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).

Allowing an inheriting class to call an ancestor method without inheriting it (i.e., skipping the inheritance chain) is not a good idea, I think. Of course with Ruby you can retroactively redefine existing methods on instantiated objects, right? (I'm a Ruby NOOB, so I may have that wrong!)

An underlying assumption about OOD is that ancestor classes don't need to worry about descendent classes changing the meaning of methods defined by the ancestors.

I think we will have to pick our poison-- Either there has to be a declaration /in the class defintion/ whether a particular method is virtual of not (C++), or we choose an object model where all methods are virtual (Java and Python) or not (VB, I think).

Paul

Hello--

David A. Black wrote:

They're written differently, but the whole self.x = y thing is just
the price we pay for, in every other situation, being allowed to drop
'self' as the receiver. It keeps things simple and clean, overall
(and it's really not *that* ugly; it's just a receiver :slight_smile: So I
wouldn't want to look at that as a rationale for overloading it,

which

would make it less simple.

I don't find the look of it at all ugly, only the asymmetry of that
particular case. But I understand why it must be so.

Also I point out the behavior of calling a private method using self as
the specified reciever: an error. So there is some precedence for
certain distinctions here. But I certainly agree with you, I do not
think it would not be wise to overload it in the manner originally
suggested.

But that's the whole purpose of the thing (whether it's M#x or self.x
or whatever) -- to constrain the nested method call (the call to #x
inside M#y1 etc.) and protect it from the redefinition of #x. I'm

not

convinced of the merits of it (I continue to tend to think that

anyone

subclassing a class should know the names of that class's methods,

and

not accidentally override them), but the idea is specifically to
provide that protection.

That's only one use case actually. Another is fine-grain control of
inheritance --one can direct methods directly to specific parents. But
I agree with your hesitation for the reason of its nonoopiness (funny
word :wink: but that's the trade off. I offered the concept of locals to
gain a middle ground in that trade --not quite as powerful, but
maintains some reusability (a very useful reusability for AOP, I might
add).

Hmmm... now that I think about it more in this light it could also be
interesting to actually define methods in this direct notation as well,
and this might lessen the shortcomings.

  class C
    def x
      "C"
    end
  end

  C.new.x #=> C

  def C#x
    "CX"
  end

  C.new.x #=> CX

T.

···

On Tue, 12 Apr 2005, Trans wrote:

Hi --

···

On Sun, 10 Apr 2005, Lionel Thiry wrote:

[I wrote:]

That's different; that's a class method.

In present ruby, yes, C::util is identical to C.util.

But I was thinking of "C::util" as an explicit namespace specification, not as a message sending to C object.

You talked about adding some "#" new operator could be inadequate as it is usually used for comments. I was just indicating "::" could do the job.

These last two don't really fit the dot semantics, and if they're
alternatives to C::util, then they're dealing with a class method
anyway (rather than the issue of limiting the effect of overriding
instance methods).

My suggestion of C#util is based on the common use of # to mean
"instance method of the named class or module". It wouldn't require
redefinition of the dot notation, nor overloading 'self' to be a
boolean flag (as in the original proposal, where 'self' means both
"the default object" and "don't redirect this to an overridden version
of the method).

And what is your opinion, now, if you take for granted that "::" semantic is redefined?

I think it's much too big a change for something like this. It would
also lead to huge amounts of code breakage. (I don't use :: for
method calls myself, but it's used a fair amount.)

David

--
David A. Black
dblack@wobblini.net

Hi --

David A. Black wrote:

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 if C#util is not defined as a with "def C.util ..." isn't it just a regular method? Or is C::util really a different sort of call to the class object?

C#util is actually the constant C plus a comment :slight_smile: This is all
speculative; there's no C#util expression in reality.

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).

Allowing an inheriting class to call an ancestor method without inheriting it (i.e., skipping the inheritance chain) is not a good idea, I think.

I don't think that's what happening here (?).

Of course with Ruby you can retroactively redefine existing methods on instantiated objects, right? (I'm a Ruby NOOB, so I may have that wrong!)

Yes. Well, it's not really retroactive -- the old method calls don't
get re-performed :slight_smile: It's perhaps better described as happening
dynamically. But, essentially, yes.

An underlying assumption about OOD is that ancestor classes don't need to worry about descendent classes changing the meaning of methods defined by the ancestors.

I think we will have to pick our poison-- Either there has to be a declaration /in the class defintion/ whether a particular method is virtual of not (C++), or we choose an object model where all methods are virtual (Java and Python) or not (VB, I think).

I don't think the area that was addressed originally by the "self"
redefinition idea was that broad, design-wise -- that is, the basic
object model isn't under review, but just something very specific.
It's the following scenario: your superclass, inside an instance
method, calls another of its instance methods, expecting a particular
behavior, but that behavior has been changed by a subclass.

David A. Black
dblack@wobblini.net

···

On Sun, 10 Apr 2005, Paul Hanchett wrote:

--
David A. Black
dblack@wobblini.net