in reply to Overloading without infinite descent (fixed by time: see Perl 5.10.1)

Warning! Stunt code!
package Before; use Acme::Damn; use overload '&{}' => sub { my $f = shift(); my $ref = damn($f); return sub { print "Stuff before\n"; my @rv = $ref->(@_); bless($ref, __PACKAGE__); return @rv; }; }; 1;
$ perl -MBefore -e 'my $foo = bless(sub { print shift()."\n" } => 'Bef +ore'); $foo->("foo"); $foo->("bar")' Stuff before foo Stuff before bar
Acme::Damn is one of the very few Acme modules that I would consider using in real life. I use it here to temporarily unbless the object, then de-ref and call, and then re-bless it. It's not quite the same as your code though - because I call the subroutine instead of using goto, there's an extra stack frame and so if you use caller() inside it it will behave differently.

Replies are listed 'Best First'.
Re^2: Overloading without infinite descent
by ELISHEVA (Prior) on Aug 03, 2009 at 10:04 UTC

    Provided $f only uses variables declared within its own subroutine body or passed in as parameters, couldn't you use the core module B::Deparse to avoid the extra stack frame (and the need to use an Acme module)?

    use strict; use warnings; use B::Deparse; { package Before; use overload '&{}' => sub { my ( $f ) = @_; my $s=B::Deparse->new()->coderef2text($f); # note: this will *NOT* work if $f uses package variables # this will also not work if $f uses certain global variables # # namely, if $f uses global variables from # the namespace where it is defined. At least for 5.8.8 # B::Deparse erases the namespace name: i.e. # { package Foo; our $X=100; my $f=sub { print "$Foo::X\n" } } # will be deparsed as: sub { print "${X}\n" }. # Since ${X} is undefined in package Before, # Perl will complain about undefined variables. $f=eval 'sub {'.$s.'}'; return sub { print "Stuff before\n"; goto &$f; } } } my $cr=bless(sub {print "Hello @_\n" },'Before'); $cr->('tweedledum', 'tweedledee'); $cr->('walrus','carpenter');

    prints

    Stuff before Hello tweedledum tweedledee Stuff before Hello walrus carpenter

    Best, beth