in reply to Re^3: Overridding subroutines called in private subroutines
in thread Overridding subroutines called in private subroutines

It's really just a nit, but you're leaking an alias to @Foo::Bar::ISA. I also use BEGIN {} instead of {} inlined modules. I'd write your program as:

#!/usr/bin/perl use strict; use warnings; BEGIN { package Foo; sub method { routine(); } sub routine { return __PACKAGE__; } } BEGIN { package Foo::Bar; our @ISA = qw( Foo ); sub routine { return __PACKAGE__; } sub method { no warnings 'redefine'; # Temporarily override routine() in the parent class. local *Foo::routine = \&routine; # Delegate to parent method. my $self = shift; $self->SUPER::method(@_); } } print "Foo: ", Foo->method, "\n"; print "Foo::Bar: ", Foo::Bar->method, "\n"; print "Foo: ", Foo->method, "\n";

Replies are listed 'Best First'.
Re^5: Overridding subroutines called in private subroutines
by TGI (Parson) on Oct 07, 2008 at 18:42 UTC

    Thanks for correcting me regarding package.

    I wanted to clarify the leaking alias nit that you referred to. If I understand the perldoc correctly, I am leaking the alias to @Foo::Bar::ISA because the our declaration creates an alias that persists across the lexical scope. So if I had enclosed the packages in braces, the leak would be prevented.

    I like your approach of using BEGIN blocks to enclose inline modules. It more closely approximates the behavior of useing them from separate files (of course you may need to add an import if you want the full goodness of use). An excellent suggestion. This would have saved me hassles on a few occasions.


    TGI says moo

      This is the leaking to which I was refering:
      $Foo::var = 'foo!'; $Bar::var = 'bar!'; package Foo; our $var; package Bar; print("$var\n"); # foo!
      $Foo::var = 'foo!'; $Bar::var = 'bar!'; { package Foo; our $var; } { package Bar; print("$var\n"); # bar! }