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

Why won't perl let my user code call SUPER, as in $foo3->SUPER::bang? I know that I don't want to call the objects bang, but will take any other bang that it inherits from (and I know that it will have one). Thanks!
#!/usr/bin/perl use strict; package BAR; sub bang { print "BANG!\n"; } package FOO; use base qw( BAR ); sub new { my $class = shift; return bless {}, $class; } sub bang { print "* please be quiet *\n" } package BAZ; use base qw( BAR ); sub bang { my $self = shift; $self->SUPER::bang(); } sub new { my $class = shift; return bless {}, $class; } package main; my $foo1 = FOO->new(); my $foo2 = BAZ->new(); my $foo3 = FOO->new(); $foo1->bang(); $foo2->bang(); $foo3->SUPER::bang();

Replies are listed 'Best First'.
Re: Why can't I call SUPER from user code?
by hv (Prior) on Mar 31, 2006 at 00:06 UTC

    Because there isn't just one SUPER: perl needs to know what class you want the superclass of. If you tell it, perl will be happy:

    $foo1->bang(); $foo2->bang(); { package BAZ; $foo3->SUPER::bang(); }

    This is needed because you may have another class:

    package QUUX; use base qw/ BAR /; sub bang { shift->SUPER::bang }
    .. which means that BAR::bang() may be called by objects that don't have ref($self) eq 'BAR'.

    Hugo

Re: Why can't I call SUPER from user code?
by eric256 (Parson) on Mar 30, 2006 at 23:34 UTC

    Basicaly thats is because your user should never be making such a decision. ;)

    On the other hand you have some redundant code in there. put your new decleration in BAR and then the other inherit it. Also if your new class doesn't want to over right the parent class then it can just leave that sub undefined.

    #!/usr/bin/perl use strict; package BAR; sub bang { print "BANG!\n"; } sub new { my $class = shift; return bless {}, $class; } package FOO; use base qw( BAR ); sub bang { print "* please be quiet *\n" } package BAZ; use base qw( BAR ); sub bang { my $self = shift; $self->SUPER::bang(); } package BAH; use base qw( BAR ); package main; my $foo1 = FOO->new(); my $foo2 = BAZ->new(); my $foo3 = BAH->new(); $foo1->bang(); $foo2->bang(); $foo3->bang();

    For future reference instead of saying "Why won't perl let my user code call SUPER, as in $foo3->SUPER::bang? " tell us what the error was.It will make life much easier.


    ___________
    Eric Hodges
      Thanks for the code pointers. It was just for illustrative purposes. It seems very un-perl like to keep you from doing this sort of thing if you want to.

        Overriding methods in the parent class lets child classes have the same interface but a different implementation. If you override the bang method, then it is normaly assumed that the changes you made are needed in order for that object to work correctly. I can't think of any case where it would be usefully to override this behaviour (of course that might just be lack of imagination on my part).


        ___________
        Eric Hodges
Re: Why can't I call SUPER from user code?
by ysth (Canon) on Mar 31, 2006 at 02:49 UTC
    First, you shouldn't do this. Second, as implemented in perl, $self->SUPER:: doesn't have anything to do with $self; SUPER is relative to the package the call is in, not the object/class the method is called on. Third, try using http://search.cpan.org/perldoc/SUPER.
Re: Why can't I call SUPER from user code?
by samtregar (Abbot) on Mar 30, 2006 at 23:36 UTC
    Because SUPER is package-scoped, which seems pretty dumb to me too. Here's how you can do something analgous from user-land, assuming single inheritence:

    my $meth = "$FOO::ISA[0]::bang"; $foo3->$meth();

    -sam