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

package Before; my %looper; use overload '&{}' => sub { my ( $f ) = @_; my $fs = overload::StrVal($f); if( $looper{$fs} ){ print "$fs got looper already\n"; return $looper{overload::StrVal($f)}; } else { my $looper = 0; my $s = sub { $looper++; print "$fs Stuff before (looper=$looper)\n"; goto &$f unless $looper > 1; }; $looper{$fs} = $s; return $s; } }; package main; ( bless sub {} => 'Before' )->() __END__ Before=CODE(0x18305e4) Stuff before (looper=1) Before=CODE(0x18305e4) got looper already Before=CODE(0x18305e4) Stuff before (looper=2)

Replies are listed 'Best First'.
Re^2: Overloading without infinite descent
by JadeNB (Chaplain) on Aug 03, 2009 at 06:42 UTC
    This gives the advertised output, and certainly avoids the infinite descent, but it seems only to do what I want for the empty sub (or any other side-effect-free sub, I suppose)—if I execute ( bless sub { print "I am a side effect\n" } => 'Before' )->(), then I am a side effect is never printed.
      Probably because that sub is never executed
        Right, but my hope was that it would be—that is, that, upon de-referencing, the ‘pre-code’ would be executed first, then the code to which the reference actually points. Thus, I'd like to see:
        ( bless sub { print "I am a side effect\n" } => 'Before' )->()
        print
        Stuff before I am a side effect