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;
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;