Mailing List Archive

SUPER:: - revised fix - is it better ?
I have an alternate patch to SUPER:: handling which allows SUPER::
to be used outside the package.

The alternate approach is to handle ->SUPER::method in two stages:

1. Look up method in the normal way, which yields a GV.
2. In that GV is a CV for the method. The 'stash' of the CV
is where we start SUPERing.


I assume there is an 'obvious' extension which would permit
->SUPER::SUPER::method

Is it agreed that this fix is superior to the earlier one?

Is it worth looking at ->SUPER::SUPER::method ?

Here is a test script:

package base;

sub amethod
{
print "base::amethod(",join(',',@_),")\n";
}

package derived;
@ISA = 'base';

sub amethod
{
print "derived::amethod(",join(',',@_),")\n";
shift->SUPER::amethod;
}

package Moreso;
@ISA = 'derived';

package main;

Moreso->amethod;
Moreso->SUPER::amethod;
__END__



And here is the patch relative to 5.002beta1


*** gv.1.c Wed Nov 22 18:27:24 1995
--- gv.c Thu Dec 7 18:36:03 1995
***************
*** 224,235 ****
--nsplit;
*nsplit = '\0';
if (strEQ(origname,"SUPER")) {
- /* Degenerate case ->SUPER::method should really lookup in original stash */
- SV *tmpstr = sv_2mortal(newSVpv(HvNAME(stash),0));
- sv_catpvn(tmpstr, "::SUPER", 7);
- stash = gv_stashpv(SvPV(tmpstr,na),TRUE);
*nsplit = ch;
! DEBUG_o( deb("Treating %s as %s::%s\n",origname,HvNAME(stash),name) );
} else {
stash = gv_stashpv(origname,TRUE);
*nsplit = ch;
--- 224,242 ----
--nsplit;
*nsplit = '\0';
if (strEQ(origname,"SUPER")) {
*nsplit = ch;
! /* Degenerate case ->SUPER::method */
! /* Do Look up ->method with no prefix to find out where it is */
! gv = gv_fetchmeth(stash, name, nend - name, 0);
! if (gv) {
! CV *cv = GvCV(gv);
! /* Now build a new package name by appending ::SUPER */
! /* to package where we found ->method */
! SV *tmpstr = sv_2mortal(newSVpv(HvNAME(CvSTASH(cv)),0));
! sv_catpvn(tmpstr, "::SUPER", 7);
! stash = gv_stashpv(SvPV(tmpstr,na),TRUE);
! DEBUG_o( deb("Treating %s as %s::%s\n",origname,HvNAME(stash),name) );
! }
} else {
stash = gv_stashpv(origname,TRUE);
*nsplit = ch;
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
On Thu, 07 Dec 1995 18:49:58 GMT, Nick.Ing-Simmons@tiuk.ti.com wrote:
>
>The alternate approach is to handle ->SUPER::method in two stages:
>
>1. Look up method in the normal way, which yields a GV.
>2. In that GV is a CV for the method. The 'stash' of the CV
> is where we start SUPERing.
>
>I assume there is an 'obvious' extension which would permit
>->SUPER::SUPER::method
>
>Is it agreed that this fix is superior to the earlier one?
>

I think there is an even more efficient approach that allows the above.

Instead of reentering the method lookup more than once,
SUPER should be implemented in gv_fetchmeth() instead. The
logic would be something like:

add an additional parameter to gv_fetchmeth() that specifies
how many gv's found should be "skipped". gv_fetchmeth() would
pretend that it never found the first "n" such methods.

$obj->SUPER::meth() would then be implemented in terms of

gv_fetchmeth(stash, name, len, level, skip=1)

and $obj->SUPER::SUPER::meth() would simply be

gv_fetchmeth(stash, name, len, level, skip=2)

etc.

This has the advantage of being faster by not actually adding SUPER::ISA's
to the symbol table, and also not invalidating the ISA cache everytime
SUPER::ISA needs to be added.

Do you see any problems with this approach?

> *nsplit = ch;
>--- 224,242 ----
> --nsplit;
> *nsplit = '\0';
> if (strEQ(origname,"SUPER")) {
> *nsplit = ch;
>! /* Degenerate case ->SUPER::method */
>! /* Do Look up ->method with no prefix to find out where it is */
>! gv = gv_fetchmeth(stash, name, nend - name, 0);
>! if (gv) {
>! CV *cv = GvCV(gv);
>! /* Now build a new package name by appending ::SUPER */
>! /* to package where we found ->method */
>! SV *tmpstr = sv_2mortal(newSVpv(HvNAME(CvSTASH(cv)),0));
>! sv_catpvn(tmpstr, "::SUPER", 7);
>! stash = gv_stashpv(SvPV(tmpstr,na),TRUE);
>! DEBUG_o( deb("Treating %s as %s::%s\n",origname,HvNAME(stash),name)
^^^^^

Shouldn't that be CvSTASH(cv) instead?

- Sarathy.
gsar@engin.umich.edu
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
Nick.Ing-Simmons@tiuk.ti.com wrote:
>
> [munch]
>
> I assume there is an 'obvious' extension which would permit
> ->SUPER::SUPER::method
>
> Is it agreed that this fix is superior to the earlier one?
>
> Is it worth looking at ->SUPER::SUPER::method ?
>
From my Objective-C background I would say NO.
SUPER is something that really makes inheritance work: You subclass
a method, and you want to *add* functionality, not cover. So you
usually start by calling super->thisMethod (or $self->SUPER::thisMethod
to stay with current perl syntax), and then add the additional code.

A need for SUPER::SUPER would show a serious design flaw in a program,
and it would violate anything encapsulation teaches us.

---
Gerd Knops ------------------------------------------ gerti@BITart.com
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
> From: Gerd Knops <gerti@BITart.com>
>
> Nick.Ing-Simmons@tiuk.ti.com wrote:
> >
> > [munch]
> >
> > I assume there is an 'obvious' extension which would permit
> > ->SUPER::SUPER::method
> >
> > Is it agreed that this fix is superior to the earlier one?
> >
> > Is it worth looking at ->SUPER::SUPER::method ?
> >
> >From my Objective-C background I would say NO.
>
> SUPER is something that really makes inheritance work: You subclass
> a method, and you want to *add* functionality, not cover. So you
> usually start by calling super->thisMethod (or $self->SUPER::thisMethod
> to stay with current perl syntax), and then add the additional code.
>
> A need for SUPER::SUPER would show a serious design flaw in a program,
> and it would violate anything encapsulation teaches us.

I agree. In fact I'd make it illegal (so long as checking for it won't
make it slower).

Tim.
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
>From: Gerd Knops <gerti@BITart.com>
>> Is it worth looking at ->SUPER::SUPER::method ?
>>
>>From my Objective-C background I would say NO.
>SUPER is something that really makes inheritance work: You subclass
>a method, and you want to *add* functionality, not cover. So you
>usually start by calling super->thisMethod (or $self->SUPER::thisMethod
>to stay with current perl syntax), and then add the additional code.
>
>A need for SUPER::SUPER would show a serious design flaw in a program,
>and it would violate anything encapsulation teaches us.

Thanks, Gerd. I've been keeping my mouth shut because I couldn't figure out
what SUPER::SUPER is supposed to mean. Too often Perl has features which
exist "because it can be done" rather than "because it should be done".

Dean
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
In <199512072225.RAA22257@aatma.engin.umich.edu>
On Thu, 07 Dec 1995 17:25:31 -0500
Gurusamy Sarathy <gsar@engin.umich.edu> writes:
>On Thu, 07 Dec 1995 18:49:58 GMT, Nick.Ing-Simmons@tiuk.ti.com wrote:
>>
>>The alternate approach is to handle ->SUPER::method in two stages:
>>
>>1. Look up method in the normal way, which yields a GV.
>>2. In that GV is a CV for the method. The 'stash' of the CV
>> is where we start SUPERing.
>>
>>I assume there is an 'obvious' extension which would permit
>>->SUPER::SUPER::method
>>
>>Is it agreed that this fix is superior to the earlier one?
>>
>
>I think there is an even more efficient approach that allows the above.
>
>Instead of reentering the method lookup more than once,
>SUPER should be implemented in gv_fetchmeth() instead. The
>logic would be something like:
>
> add an additional parameter to gv_fetchmeth() that specifies
> how many gv's found should be "skipped". gv_fetchmeth() would
> pretend that it never found the first "n" such methods.
>
> $obj->SUPER::meth() would then be implemented in terms of
>
> gv_fetchmeth(stash, name, len, level, skip=1)
>
> and $obj->SUPER::SUPER::meth() would simply be
>
> gv_fetchmeth(stash, name, len, level, skip=2)
>
> etc.

Sounds plausible - do we have SUPER::SUPER:: or SUPER2:: ?

>
>This has the advantage of being faster by not actually adding SUPER::ISA's
>to the symbol table, and also not invalidating the ISA cache everytime
>SUPER::ISA needs to be added.

Larry and I don't think that *aliasing* the ISA's does invalidate
the cache.

I use C code equivalent of :

*Package::SUPER::ISA = \@Package::ISA;

And I certainly don't increment sub_generation.

>
>Do you see any problems with this approach?
>
By not creating the @ISA's you are forcing re-lookup each time,
and don't cache where you found methods.
That said this latest SUPER:: prefix does always does extra
lookup anyway - hmm.

(What use is SUPER outside a package/class? I have only ever used
*in* a class - for obvious use of calling base class's version
as part of the derived version.)
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
> From: Nick Ing-Simmons <nik@tiuk.ti.com>

> The previous 'fix' to 5.002beta1 works if SUPER:: is only used *in*
> the package - and is faster as it uses 'current' stash rather
> than another gv_fetchmeth().
>
> package Someclass;
> @ISA = Baseclass;
>
> sub method
> {
> my $self = shift;
> $self->SUPER::method(@_); # example
> }
>
> This new fix allows :
>
> package main;
>
> $obj = Someclass->new(...);
>
> $obj->SUPER::method(...);
>
> To call Baseclass::method.
>
> is this desirable?

As Gerd pointed out, this breaks encapsulation. On the other hand if it's
difficult to prevent, or if preventing it has a high runtime cost, then I
wouldn't worry about it.


Dean
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
On Fri, 08 Dec 1995 08:54:34 GMT, Nick Ing-Simmons wrote:
>On Thu, 07 Dec 1995 17:25:31 -0500
>Gurusamy Sarathy <gsar@engin.umich.edu> writes:
>>>Is it agreed that this fix is superior to the earlier one?
>>
>>I think there is an even more efficient approach that allows the above.
>>
>> add an additional parameter to gv_fetchmeth() that specifies
>> how many gv's found should be "skipped". gv_fetchmeth() would
>> pretend that it never found the first "n" such methods.
>>
>> $obj->SUPER::meth() would then be implemented in terms of
>>
>> gv_fetchmeth(stash, name, len, level, skip=1)
>>
>> and $obj->SUPER::SUPER::meth() would simply be
>>
>> gv_fetchmeth(stash, name, len, level, skip=2)
>>
>> etc.
>
>Sounds plausible - do we have SUPER::SUPER:: or SUPER2:: ?

I'll go with SUPER::SUPER::

>>
>>This has the advantage of being faster by not actually adding SUPER::ISA's
>>to the symbol table, and also not invalidating the ISA cache everytime
>>SUPER::ISA needs to be added.
>
>Larry and I don't think that *aliasing* the ISA's does invalidate
>the cache.
>
>I use C code equivalent of :
>
>*Package::SUPER::ISA = \@Package::ISA;
>
>And I certainly don't increment sub_generation.

I see what you mean. But even so, adding the glob
entry to the symbol table is rather expensive.

>
>>
>>Do you see any problems with this approach?
>>
>By not creating the @ISA's you are forcing re-lookup each time,
>and don't cache where you found methods.
>That said this latest SUPER:: prefix does always does extra
>lookup anyway - hmm.

Under either approach, gv_fetchmeth() needs extra code that will allow
caching of more than one "topgv".

>
>(What use is SUPER outside a package/class? I have only ever used
> *in* a class - for obvious use of calling base class's version
> as part of the derived version.)
>

Another good reason not to add it to the symbol table (and thereby
making it a global).

- Sarathy.
gsar@engin.umich.edu
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
On Fri, 08 Dec 1995 08:54:34 GMT, Nick Ing-Simmons wrote:
>On Thu, 07 Dec 1995 17:25:31 -0500
>Gurusamy Sarathy <gsar@engin.umich.edu> writes:
>>>Is it agreed that this fix is superior to the earlier one?
>>
>>I think there is an even more efficient approach that allows the above.
>>
>> add an additional parameter to gv_fetchmeth() that specifies
>> how many gv's found should be "skipped". gv_fetchmeth() would
>> pretend that it never found the first "n" such methods.
>>
>> $obj->SUPER::meth() would then be implemented in terms of
>>
>> gv_fetchmeth(stash, name, len, level, skip=1)
>>
>> and $obj->SUPER::SUPER::meth() would simply be
>>
>> gv_fetchmeth(stash, name, len, level, skip=2)
>>
>> etc.
>
>Sounds plausible - do we have SUPER::SUPER:: or SUPER2:: ?

I'll go with SUPER::SUPER::

>>
>>This has the advantage of being faster by not actually adding SUPER::ISA's
>>to the symbol table, and also not invalidating the ISA cache everytime
>>SUPER::ISA needs to be added.
>
>Larry and I don't think that *aliasing* the ISA's does invalidate
>the cache.
>
>I use C code equivalent of :
>
>*Package::SUPER::ISA = \@Package::ISA;
>
>And I certainly don't increment sub_generation.

I see what you mean. But even so, adding the glob
entry to the symbol table is rather expensive.

>
>>
>>Do you see any problems with this approach?
>>
>By not creating the @ISA's you are forcing re-lookup each time,
>and don't cache where you found methods.
>That said this latest SUPER:: prefix does always does extra
>lookup anyway - hmm.

Under either approach, gv_fetchmeth() needs extra code that will allow
caching of more than one "topgv".

>
>(What use is SUPER outside a package/class? I have only ever used
> *in* a class - for obvious use of calling base class's version
> as part of the derived version.)
>

Another good reason not to add it to the symbol table (and thereby
making it a global).

- Sarathy.
gsar@engin.umich.edu
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
On Fri, 08 Dec 1995 10:58:16 GMT, Tim Bunce wrote:
>> From: Gerd Knops <gerti@BITart.com>
>> A need for SUPER::SUPER would show a serious design flaw in a program,
>> and it would violate anything encapsulation teaches us.
>
>I agree. In fact I'd make it illegal (so long as checking for it won't
>make it slower).
>

Same here.

- Sarathy.
gsar@engin.umich.edu
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
> From: Gurusamy Sarathy <gsar@engin.umich.edu>
>
> On Fri, 08 Dec 1995 08:54:34 GMT, Nick Ing-Simmons wrote:
> >On Thu, 07 Dec 1995 17:25:31 -0500
> >
> >Sounds plausible - do we have SUPER::SUPER:: or SUPER2:: ?
>
> I'll go with SUPER::SUPER::

Are there _any_ good reasons for supporting the concept of SUPER::SUPER ?

Personally I think it's a bad idea.

Tim.
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
In <9512080552.AA22921@Homer.BITart.com>
On Thu, 7 Dec 95 23:52:39 -0600
<gerti@BITart.com> writes:
>Nick.Ing-Simmons@tiuk.ti.com wrote:
>> Is it agreed that this fix is superior to the earlier one?
>>
>> Is it worth looking at ->SUPER::SUPER::method ?
>>
From my Objective-C background I would say NO.
>SUPER is something that really makes inheritance work: You subclass
>a method, and you want to *add* functionality, not cover. So you
>usually start by calling super->thisMethod (or $self->SUPER::thisMethod
>to stay with current perl syntax), and then add the additional code.

So

package main;
$someobj->SUPER::method;

Is not needed either, so my earlier patch is 'sufficient'.

>
>A need for SUPER::SUPER would show a serious design flaw in a program,
>and it would violate anything encapsulation teaches us.
>
Good - because it would be messy.
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
On Fri, 08 Dec 1995 17:21:33 GMT, Tim Bunce wrote:
>> From: Gurusamy Sarathy <gsar@engin.umich.edu>
>> On Fri, 08 Dec 1995 08:54:34 GMT, Nick Ing-Simmons wrote:
>> >
>> >Sounds plausible - do we have SUPER::SUPER:: or SUPER2:: ?
>>
>> I'll go with SUPER::SUPER::
>
>Are there _any_ good reasons for supporting the concept of SUPER::SUPER ?
>Personally I think it's a bad idea.

After trying to come up with even some lame excuse for a reason, I tend to
agree. I wonder why Larry might have brought it up in the first place...

- Sarathy.
gsar@engin.umich.edu
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
In <9512081533.AA08189@poplar027>
On Fri, 8 Dec 1995 09:33:19 -0600
Dean Roehrich <roehrich@cray.com> writes:
>>From: Gerd Knops <gerti@BITart.com>
>>> Is it worth looking at ->SUPER::SUPER::method ?
>>>
>>
>>A need for SUPER::SUPER would show a serious design flaw in a program,
>>and it would violate anything encapsulation teaches us.
>
>Thanks, Gerd. I've been keeping my mouth shut because I couldn't figure out
>what SUPER::SUPER is supposed to mean. Too often Perl has features which
>exist "because it can be done" rather than "because it should be done".
>
Thanks for speaking up Dean - it would seem that we all agree
that SUPER::SUPER:: is undesirable.

I only mentioned it because Larry did some time back.
It is possible but messy - let's not do it.

Now the 'is it better' question - the reason for looking at this
was another Larry comment along the lines that 'we had better document that it
can only be used in the package'.

I think it *should* only be used _in the package_.

The previous 'fix' to 5.002beta1 works if SUPER:: is only used *in*
the package - and is faster as it uses 'current' stash rather
than another gv_fetchmeth().

package Someclass;
@ISA = Baseclass;

sub method
{
my $self = shift;
$self->SUPER::method(@_); # example
}

This new fix allows :

package main;

$obj = Someclass->new(...);

$obj->SUPER::method(...);

To call Baseclass::method.

is this desirable?
Re: SUPER:: - revised fix - is it better ? [ In reply to ]
In <9512081635.AA08656@poplar027>
On Fri, 8 Dec 1995 10:35:11 -0600
Dean Roehrich <roehrich@cray.com> writes:
>> This new fix allows :
>>
>> package main;
>>
>> $obj = Someclass->new(...);
>>
>> $obj->SUPER::method(...);
>>
>> To call Baseclass::method.
>>
>> is this desirable?
>
>As Gerd pointed out, this breaks encapsulation. On the other hand if it's
>difficult to prevent, or if preventing it has a high runtime cost, then I
>wouldn't worry about it.
>
It is easy to prevent, and allowing it has higher cost.

Consider this later patch withdrawn.