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

Update: I missed the line about "I could arrange that the constructor wraps the subroutine at construction time, rather than de-referencing time". My apologies to the OP. This won't answer the OP's question, but maybe it will be helpful to someone interested in the more general solution "how do I..."

Is your goal to wrap the call to $f in a sub that inserts some before (or maybe before and after behavior)? Or it is to do that and insure that the blessed code ref and $f have the same memory address? And if so, why is this important?

If you don't need the same memory address, you could simply define a constructor that wraps the subroutine in another subroutine, like this:

{ package Before; sub new { my ($sClass,$f) = @_; my $fBefore= sub { print "Special stuff for class $sClass\n"; goto &$f }; return bless($fBefore,$sClass); } } { package AlsoBefore; our @ISA=qw(Before); } my $f1=Before->new(sub {print "Hello world!\n"}); my $f2=Before->new(sub {print "Bonjour, le monde!\n"}); my $f3=Before->new(sub {print "Guten tag, die welt!\n"}); my $f4=AlsoBefore->new(sub {print "Boker tov, olam!\n"}); $f1->(); $f2->(); $f3->(); $f4->();

which prints

Special stuff for class Before Hello world! Special stuff for class Before Bonjour, le monde! Special stuff for class Before Guten tag, die welt! Special stuff for class AlsoBefore Boker tov, olam!

Best, beth

Replies are listed 'Best First'.
Re^2: Overloading without infinite descent
by JadeNB (Chaplain) on Aug 03, 2009 at 07:30 UTC
    I agree that, if I'm willing to wrap at construction time, then the problem may be solved exactly as you describe. I was just wondering (specifically for the reason that I've described—and because I'm stubborn and want to do something the first way that occurred to me :-)—but more generally because it seems like an interesting, and possibly useful, thing to do) whether it's possible to get at the ‘true’ behaviour of an object which is subject to overloading.

    A use case (which is not my actual situation) might go as follows: Imagine that Perl prototypes don't exist, and we're trying to create them. Then one could imagine wanting to write code like this:

    package Prototype; use overload '&{}' => sub { my ( $f ) = @_; return sub { check_arguments(@_); goto &$f; }; }; sub i_know_what_im_doing { my $f = shift; goto &$f; }
    so that executing
    $f->(@args)
    would check the prototype, but executing
    $f->i_know_what_im_doing(@args)
    wouldn't.

    (It's not a very good use case, because we have to store the prototype somewhere, and, if we are good and store it in the object, then it's easy to find a way around the problem. :-) )

      Your question stands on its own merits, of course, but I'm still puzzled as to why one would want to do it. The syntax you describe above could be accomplished without overloading simply by using the wrapped functions reference address as a key into a hash that stores the original code reference. This would also give you the advantage of making the definition of i_know_what_im_doing class specific. Perhaps you could suggest another use case where overloading really is essential? The modified routine for those interested (I expect the OP could easily write it on his/her own).

      Best, beth

      Update: distinguished my question from OP's and clarified my own question which is still about why