www.digitalmars.com         C & C++   DMDScript  

D - invoking a method through 'this'

reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Is there a way to specifically invoke a method implemented within the
enclosing class? One can explicitly invoke the super class implementation
(via 'super.'), but what about this scenario:

class A
{
       private Object[char[]]  map;

       Object get (char[] key)
       {
            return map[key];
       }

       Object extract (char[] key)
       {
            // we want to invoke get() from this class;
            // not from some subclass implementation
            Object o = this.get (key);
             if (o)
                 delete map [key];
             return o;
       }
}


class B : A
{
      Object get (char[] key)
      {
            Object o = super.get (key);
            // do all kinds of other stuff ...
      }
}

When instantiated as a Class B instance, A.extract() does *not* want to
invoke the overridden version of get() ... it just wants to use the known
version within its containing class ...

Can D handle this case?

- Kris
Apr 17 2004
parent reply "Walter" <newshound digitalmars.com> writes:
The way to do that is to have two functions, a "get()" which is virtual
which calls a private "Aget()". Then, instead of this.get(), use Aget().

"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c5ql8n$4ot$1 digitaldaemon.com...
 Is there a way to specifically invoke a method implemented within the
 enclosing class? One can explicitly invoke the super class implementation
 (via 'super.'), but what about this scenario:

 class A
 {
        private Object[char[]]  map;

        Object get (char[] key)
        {
             return map[key];
        }

        Object extract (char[] key)
        {
             // we want to invoke get() from this class;
             // not from some subclass implementation
             Object o = this.get (key);
              if (o)
                  delete map [key];
              return o;
        }
 }


 class B : A
 {
       Object get (char[] key)
       {
             Object o = super.get (key);
             // do all kinds of other stuff ...
       }
 }

 When instantiated as a Class B instance, A.extract() does *not* want to
 invoke the overridden version of get() ... it just wants to use the known
 version within its containing class ...

 Can D handle this case?

 - Kris
May 26 2004
next sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Thanks Walter; but that's hardly what I'd call "language support" <g>. And
it's not very efficient unless it happens to also be inline-able, assuming
development constraints are relaxed enough to permit -inline usage ...

Is it not possible to bind explicit use of "this.method()" to the enclosing
class, rather then any derivative overload?

- Kris


"Walter" <newshound digitalmars.com> wrote in message
news:c92nkt$2mun$2 digitaldaemon.com...
 The way to do that is to have two functions, a "get()" which is virtual
 which calls a private "Aget()". Then, instead of this.get(), use Aget().

 "Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
 news:c5ql8n$4ot$1 digitaldaemon.com...
 Is there a way to specifically invoke a method implemented within the
 enclosing class? One can explicitly invoke the super class
implementation
 (via 'super.'), but what about this scenario:

 class A
 {
        private Object[char[]]  map;

        Object get (char[] key)
        {
             return map[key];
        }

        Object extract (char[] key)
        {
             // we want to invoke get() from this class;
             // not from some subclass implementation
             Object o = this.get (key);
              if (o)
                  delete map [key];
              return o;
        }
 }


 class B : A
 {
       Object get (char[] key)
       {
             Object o = super.get (key);
             // do all kinds of other stuff ...
       }
 }

 When instantiated as a Class B instance, A.extract() does *not* want to
 invoke the overridden version of get() ... it just wants to use the
known
 version within its containing class ...

 Can D handle this case?

 - Kris
May 26 2004
next sibling parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Kris wrote:

 Thanks Walter; but that's hardly what I'd call "language support" <g>.
It is not such a common thing that you could expect special features in helping you to do so. Any any special feature would probably be not much simpler than the current solution.
 And
 it's not very efficient unless it happens to also be inline-able, assuming
 development constraints are relaxed enough to permit -inline usage ...
Of course it is simple to inline such a thing. The routine that has to be inlined is private, so it is in the same module as the calling routine. If the outer routine is nothing but a wrapper, why should it not be inlinable? And if you try to work without -inline, you should not expect any efficiency anyway.
 Is it not possible to bind explicit use of "this.method()" to the
 enclosing class, rather then any derivative overload?
That would be rather artificial: "this" has a certain type and using ".method()" on this type has a certain meaning. Changing this meaning in that special case will cause all kinds of problems.
May 26 2004
parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
I agree in general Norbert, but

"Norbert Nemec" wrote
 And if you try to work without -inline, you should not expect any
efficiency
 anyway.
That's a bit draconian <g>
 That would be rather artificial: "this" has a certain type and using
 ".method()" on this type has a certain meaning. Changing this meaning in
 that special case will cause all kinds of problems.
I seem to recall using exactly this syntax in Java to resolve this very issue. In other words, prefixing a method call with "this." constrains the Java call to within the enclosing class. This is really very helpful when you are implementing an Interface, but want to avoid clashing with any potential subclass implementation. I'm not sure that it does change the meaning of "this." at all, but I guess Walter has the definitive word on that ... Cheers, - Kris
May 26 2004
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c92pp0$2qsf$1 digitaldaemon.com...
 Is it not possible to bind explicit use of "this.method()" to the
enclosing
 class, rather then any derivative overload?
On second thought, you're right. I'll make the change.
May 26 2004
parent reply Hauke Duden <H.NS.Duden gmx.net> writes:
Walter wrote:
 "Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
 news:c92pp0$2qsf$1 digitaldaemon.com...
 
Is it not possible to bind explicit use of "this.method()" to the
enclosing
class, rather then any derivative overload?
On second thought, you're right. I'll make the change.
I think that'd be a mistake. There is a programming style (often used by JAVA programmers) that does not use any prefixes for member variables. Instead, if the name of a member variable should conflict with a local variable, these people use this.varname to access the member. The same should be true for methods, especially since D supports local methods. It is also the only consistent way. "this" is a reference to the current object, so <reference>.method() should behave the same, no matter if you use a reference variable or "this". Special handling of "this" will just make everything more complicated and harder to understand. If you need to call a method in a fully qualified way, why not use the normal way? I.e. CLASSNAME.method() ? Hauke
May 26 2004
next sibling parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Perhaps I misunderstand you HD, but I think we're saying the same thing
here. The use of "this." with a member variable is being explicit about
which instance is referred to (when there's confusion with an argument/auto
of the same name). The same should hold true with member functions.

The "super." prefix is present for similar reasons when you want to be
explicit about a superclass member variable or method. As it stands right
now, the "this." prefix is explicit regarding member variables but not
methods (because it currently includes subclass methods also). I'm asking
that it be changed such that "this." behaves the same for both variables and
methods.

The default "fully virtualized" behavior (sans prefix) is not affected by
this whatsoever.

As noted before, this situation crops up mostly when implementing an
Interface and you want to constrain behavior from any given superclass to
within that particular superclass only. That is, the interface method(s)
might be reimplemented by a subclass, but the *internal* behavior of the
original implementing class remains constant because explicit method calls
invoke its own methods rather than having them overridden. Not being able to
explicitly state "I want *that* particular method" can lead to all kinds of
nasty bugs when someone (at a later date) derives a superclass with methods
of the same signature ... this is perhaps a dark-side of treating methods as
virtual by default?

 If you need to call a method in a fully qualified way, why not use the
 normal way? I.e. CLASSNAME.method() ?
Surely that would assume the method were static? It would certainly be nice to fully qualify the method in some fashion, other than "super." or "this."; I vaguely recall Java does that with some ClassName.this.method() incantation. - Kris "Hauke Duden" wrote:
 I think that'd be a mistake. There is a programming style (often used by
 JAVA programmers) that does not use any prefixes for member variables.
 Instead, if the name of a member variable should conflict with a local
 variable, these people use this.varname to access the member.

 The same should be true for methods, especially since D supports local
 methods. It is also the only consistent way. "this" is a reference to
 the current object, so <reference>.method() should behave the same, no
 matter if you use a reference variable or "this". Special handling of
 "this" will just make everything more complicated and harder to
understand.
 If you need to call a method in a fully qualified way, why not use the
 normal way? I.e. CLASSNAME.method() ?

 Hauke
May 26 2004
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message
news:c939g8$h6c$1 digitaldaemon.com...
 I think that'd be a mistake. There is a programming style (often used by
 JAVA programmers) that does not use any prefixes for member variables.
 Instead, if the name of a member variable should conflict with a local
 variable, these people use this.varname to access the member.
I think the this.member() being direct, rather than virtual, call is what Java does, and I haven't seen it listed as a mistake in Java's design.
 The same should be true for methods, especially since D supports local
 methods. It is also the only consistent way. "this" is a reference to
 the current object, so <reference>.method() should behave the same, no
 matter if you use a reference variable or "this". Special handling of
 "this" will just make everything more complicated and harder to
understand. It already does this with super.member, this.member just makes it more consistent (depending on how you look at it).
 If you need to call a method in a fully qualified way, why not use the
 normal way? I.e. CLASSNAME.method() ?
That usually caused problems for me when cutting & pasting code :-(
May 26 2004
parent reply Hauke Duden <H.NS.Duden gmx.net> writes:
Walter wrote:
 "Hauke Duden" <H.NS.Duden gmx.net> wrote in message
 news:c939g8$h6c$1 digitaldaemon.com...
 
I think that'd be a mistake. There is a programming style (often used by
JAVA programmers) that does not use any prefixes for member variables.
Instead, if the name of a member variable should conflict with a local
variable, these people use this.varname to access the member.
I think the this.member() being direct, rather than virtual, call is what Java does, and I haven't seen it listed as a mistake in Java's design.
If that is true then it proves my point. I have been programming on and off in JAVA for the last half a dozen years and I didn't know that. I don't use the "this.XXX" style, so that's why I never tripped about this, but if I had read "this.method()" I would sure as hell have assumed it to be the same as CLASSNAME ref=this; ref.method(); It is hugely inconsistent if it isn't!
The same should be true for methods, especially since D supports local
methods. It is also the only consistent way. "this" is a reference to
the current object, so <reference>.method() should behave the same, no
matter if you use a reference variable or "this". Special handling of
"this" will just make everything more complicated and harder to
understand. It already does this with super.member, this.member just makes it more consistent (depending on how you look at it).
But super is not a reference - if it was then it would be the same as "this", wouldn't it? It is an alias for the base class name.
If you need to call a method in a fully qualified way, why not use the
normal way? I.e. CLASSNAME.method() ?
That usually caused problems for me when cutting & pasting code :-(
Urrrgh. You publicly admit to frequently cutting & pasting? Don't you know that it is the greatest sin in programming? ;) But seriously, it doesn't have to be the class name. typeof(this), as someone else mentioned, could be an alternative way to do this (using the classname should still be possible, though). As long as "this" stays a normal reference. Besides, when you only have super and this for qualification then you still can't access overloaded methods that are lower in the hierarchy. Hauke
May 27 2004
parent reply "Walter" <newshound digitalmars.com> writes:
I made a mistake. Java does not allow this.method() to access overridden
methods. So I'll back out that change - we'll go with the
typeof(this).method().
May 27 2004
parent Ant <Ant_member pathlink.com> writes:
In article <c94duq$25kf$1 digitaldaemon.com>, Walter says...
I made a mistake. Java does not allow this.method() to access overridden
methods. So I'll back out that change - we'll go with the
typeof(this).method().
in java you can do: ClassName.this.method(); typeof(this).method(); looks like a static method to me: not really what we a talking about. Ant
May 27 2004
prev sibling parent Andy Friesen <andy ikagames.com> writes:
Hauke Duden wrote:

 Walter wrote:
 
 "Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
 news:c92pp0$2qsf$1 digitaldaemon.com...

 Is it not possible to bind explicit use of "this.method()" to the
 enclosing  class, rather then any derivative overload?
On second thought, you're right. I'll make the change.
I think that'd be a mistake. There is a programming style (often used by JAVA programmers) that does not use any prefixes for member variables. Instead, if the name of a member variable should conflict with a local variable, these people use this.varname to access the member. If you need to call a method in a fully qualified way, why not use the normal way? I.e. CLASSNAME.method() ?
I second this, since you could do typeof(this).method(); -- andy
May 26 2004
prev sibling parent reply Ant <Ant_member pathlink.com> writes:
In article <c92nkt$2mun$2 digitaldaemon.com>, Walter says...
The way to do that is to have two functions, a "get()" which is virtual
which calls a private "Aget()". Then, instead of this.get(), use Aget().
I'm afraid that is the correct answer. if get() if not suppouse to be overwritten make it final or private. You want to through away one of the main OO design features. I say that your implementation design should be reviwed, not the language. is this a real life scenario you need to support? Ant
"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c5ql8n$4ot$1 digitaldaemon.com...
 Is there a way to specifically invoke a method implemented within the
 enclosing class? One can explicitly invoke the super class implementation
 (via 'super.'), but what about this scenario:

 class A
 {
        private Object[char[]]  map;

        Object get (char[] key)
        {
             return map[key];
        }

        Object extract (char[] key)
        {
             // we want to invoke get() from this class;
             // not from some subclass implementation
             Object o = this.get (key);
              if (o)
                  delete map [key];
              return o;
        }
 }


 class B : A
 {
       Object get (char[] key)
       {
             Object o = super.get (key);
             // do all kinds of other stuff ...
       }
 }

 When instantiated as a Class B instance, A.extract() does *not* want to
 invoke the overridden version of get() ... it just wants to use the known
 version within its containing class ...

 Can D handle this case?

 - Kris
May 27 2004
parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
It is a real-life scenario Antonio, but one that can be (has been) changed.
It does tend to crop up though, especially when working with interfaces (the
tendency is to implement the interface methods, and then use them within the
enclosing class for whatever purpose without regard to the fact those
methods may well be overridden at some future point).

I guess it's perhaps an OO boundary condition, since I could personally make
an argument for both perspectives. Having said that, I think Walter has this
condition covered for those who wish to be extra careful.

 - Kris


"Ant" <Ant_member pathlink.com> wrote in message
news:c95b2i$1a8u$1 digitaldaemon.com...
 In article <c92nkt$2mun$2 digitaldaemon.com>, Walter says...
The way to do that is to have two functions, a "get()" which is virtual
which calls a private "Aget()". Then, instead of this.get(), use Aget().
I'm afraid that is the correct answer. if get() if not suppouse to be overwritten make it final or private. You want to through away one of the main OO design features. I say that your implementation design should be reviwed, not the language. is this a real life scenario you need to support? Ant
"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c5ql8n$4ot$1 digitaldaemon.com...
 Is there a way to specifically invoke a method implemented within the
 enclosing class? One can explicitly invoke the super class
implementation
 (via 'super.'), but what about this scenario:

 class A
 {
        private Object[char[]]  map;

        Object get (char[] key)
        {
             return map[key];
        }

        Object extract (char[] key)
        {
             // we want to invoke get() from this class;
             // not from some subclass implementation
             Object o = this.get (key);
              if (o)
                  delete map [key];
              return o;
        }
 }


 class B : A
 {
       Object get (char[] key)
       {
             Object o = super.get (key);
             // do all kinds of other stuff ...
       }
 }

 When instantiated as a Class B instance, A.extract() does *not* want to
 invoke the overridden version of get() ... it just wants to use the
known
 version within its containing class ...

 Can D handle this case?

 - Kris
May 27 2004
parent reply Ant <Ant_member pathlink.com> writes:
In article <c95ctf$1d2a$1 digitaldaemon.com>, Kris says...
It is a real-life scenario Antonio, but one that can be (has been) changed.
It does tend to crop up though, especially when working with interfaces (the
tendency is to implement the interface methods, and then use them within the
enclosing class for whatever purpose without regard to the fact those
methods may well be overridden at some future point).
ah... code first and ask question later... ;)
I guess it's perhaps an OO boundary condition, since I could personally make
an argument for both perspectives.
(What would you call it? "sometimes polimorphic"?) That is the function of "final" (for methods) in java. Do we have it in D? if not we will need it. (I was on the D specs but couldn't find it. The attribute "final" exists but is not described) Ant
May 27 2004
parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
"Ant" wrote:
 ah... code first and ask question later... ;)
The only way to be absolutely sure someone won't screw with a class implementation is to make everything private <g>. One can essentially guarantee someone will (deliberately or accidently) find a way to subvert any initial assumptions. A reasonable approach to avoid much of this is to make two version of each clearly abusable class: an immutable, plus a mutable subclass. Although that doesn't have much (if any) bearing on the current topic.
 (What would you call it? "sometimes polimorphic"?)
"AC/DC" :-) Ok, Ok, this is a serious topic.
 That is the function of "final" (for methods) in java.
 Do we have it in D?
Yep, D does support "final" methods.
May 27 2004
parent Ant <Ant_member pathlink.com> writes:
In article <c95h7a$1jit$1 digitaldaemon.com>, Kris says...
"Ant" wrote:
 ah... code first and ask question later... ;)
The only way to be absolutely sure someone won't screw with a class implementation is to make everything private <g>. One can essentially guarantee someone will (deliberately or accidently) find a way to subvert any initial assumptions. A reasonable approach to avoid much of this is to make two version of each clearly abusable class: an immutable, plus a mutable subclass. Although that doesn't have much (if any) bearing on the current topic.
 (What would you call it? "sometimes polimorphic"?)
"AC/DC" :-) Ok, Ok, this is a serious topic.
Yes, and I don't think we should have a way to do it. either a method is virtual or it's not. well, it's more of a feel. I didn't do any deep analizes. But I think I should the more I think of this the more dangerous it seems. I'll try read Walter's posts here (tonight) to see if an emergency post against this is necessary. Ant
May 28 2004