Perl Advent Calendar 2007-12-09

E.L.F.

by Jerrad Pierce

Actually published 12-26

Sub::Versive permits you to install stackable pre- and post- execution chunks of code on arbitrary subroutines. An interesting use one might attempt with the module is to employ an lvalue subroutine with a post handler to make more than mere mutators e.g; reimplement substr, etc. Alas, due to the slight of hand used to achieve these results—symbol smashing and iteration over cached lists of coderefs—the module is not compatible with lvalue subroutines. What might one subvert then? Well, as our code sample demonstrates, among other things it's possible to setup some debugging at a distance. The output is:

Entering _bar(1 1 2 3)...
baz quux
Exiting _bar()...
Entering _bar(99)...
baz quux
Exiting _bar()...

Finally, note that the 0.01 SYNOPSIS has reversed the print statements for prepend and append.

mod9.pl


   1 use Sub::Versive ':all';
   2 
   3 #Unable to munge @_
   4 prepend_to_sub{ print STDERR "Entering _bar(@_)...\n" } &There::_bar;
   5 #Unable to access the sub's return value, "modify" it by returning
   6  append_to_sub{ print STDERR "Exiting _bar(@rv)...\n" } &There::_bar;
   7 
   8 #Make a subroutine available everywhere via an unqualified name;
   9 #this *must* happen after mungers have been installed
  10 builtinify &There::foo;
  11 
  12 foo(1,1,2,3);
  13 
  14 package Here;
  15 foo(99);
  16 
  17 package There;
  18 sub foo{
  19     _bar(@_);
  20 }
  21 
  22 sub _bar{
  23     print "baz quux\n";
  24     return 9;
  25 }