sub wrap { my ($name, $outer) = @_; my $inner = \&$name; *{$name} = sub { $outer->($inner, @_); }; } sub foo { print "foo\n"; } wrap 'foo', sub { my $foo = shift; print "called foo with (@_)\n"; $foo->(@_); }; foo('args'); wrap 'foo', sub { my $foo = shift; print "called AGAIN foo with (@_)\n"; $foo->(@_); }; foo('more args'); __END__ called foo with (args) foo called AGAIN foo with (more args) called foo with (more args) foo