redhotpenguin has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

Today I was examining a method in my codebase and I wanted to test changes to it, so I overloaded the method using the glob operator like so.

#!perl use strict; use warnings; use foo::bar; my $bar = foo::bar->new; $bar->foo; # prints "FOO!" *foo::bar::foo = sub { my $self = shift; $self->SUPER::foo; }; $bar->foo; # results in "Can't locate object method \"foo\" via packag +e \"main\" at foo.pl line 12 pacakge foo; use strict; use warnings; sub foo { print "FOO!"; } 1; package foo::bar; use strict; use warnings; use base 'foo'; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; } sub foo { my $self = shift; # Set some attributes on $self - not done in overloaded method $self->SUPER::foo; } 1;
What's going on here? It seems that when sub foo() was redefined, calls to SUPER were passed to main. I dumped @ISA for both sub calls and it's unchanged.

Replies are listed 'Best First'.
Re: SUPER lost in overloaded method
by hv (Prior) on Feb 10, 2006 at 00:38 UTC

    The SUPER:: of a method is determined based on the package in which the method was compiled, not on the package in which it is called, nor the package in which it was found.

    You can achieve the effect you want by compiling it in the right package:

    { package foo::bar; *foo = sub { my $self = shift; $self->SUPER::foo; }; }

    There has been a fair bit of discussion over the years on the perl development lists about whether this behaviour is wrongly defined, but it's unlikely to be changed in any version of perl5.

    Hugo

Re: SUPER lost in overloaded method
by chromatic (Archbishop) on Feb 10, 2006 at 07:19 UTC

    The SUPER module provides workarounds for this.