http://qs321.pair.com?node_id=375131

Tuppence has asked for the wisdom of the Perl Monks concerning the following question:

I want to 'push' a subroutine into a class. By this I mean if a class has a 'foo' method, I want to grab a reference to the old subroutine, and replace it with a subroutine that Does Other Stuff and then calls the old one.

This is made slightly trickier in that I want to do it in a way that I can use it across multiple modules, as long as the routine I want to add is the same.

So, for instance
package Parenthise; sub parenthise { my($class, $field_name) = @_; my $fullname = join ('::', $class, $field_name); my $coderef; my $set_coderef = "\$coderef = $fullname;"; eval $set_coderef; my $replace_sub = sub { my ($self, $value) = @_; if(@_ > 1){ return $coderef->($self); }else{ return $coderef->($self, "($value)"); } }; # here's where the trouble starts my $switcheroo = sprintf(<<"HERE" , $class, $field_name, $ +field_name); package %s; undef &{ *%s{CODE} }; *%s = \$coderef; HERE eval $switcheroo; } 1;
package SomePackage; use Class::MethodMaker get_set => [qw/value/], new_with_init => 'new'; use Parenthise; Parenthise::parenthise(__PACKAGE__, 'value'); 1;
use Somepackage; my $thing = Somepackage->new(); $thing->value('bar'); $thing->value eq '(bar)';

Note that this isn't exactly what my code is, my actual code is a bit more complicated by the fact that there are multiple fields and the function is actually figuring out which fields to change automatically.

I haven't tested the code posted in this comment, as all the interesting bits are copy and paste from my code.

I am trying to get this to work under strict, which is why the undef in the switcheroo eval.

Thanks tons for any and all help in advance, I've been banging my head on this for quite a while trying various things.

20040720 Edit by ysth: break up (accidental?) extremely long code line