Have you ever wanted to redefine a subroutine while your program is running? It's possible -- and not involving closures or other manipulations. Here's a little demonstration.
Note a few things:
- First, we define a subroutine called my_sub
- Next, we define a scalar containing the new subroutine -- this can come from anywhere. It's only hardcoded here for demonstration purposes.
- We also define a scalar called my_sub just to show that we're not stomping all over *everything* in the symbol table.
- The real magic is in the eval statement -- we assign the interpolated (and then compiled!) subroutine in $soft_sub anonymously to $sub_ref!
- After a couple of demonstrations of &my_sub and $my_sub, we undefine &my_sub using symbol table access.
- Next, we use typeglob access to assign our anonymous new subroutine to the CODE container of *my_sub.
- Finally, we call the new subroutine and then demonstrate that $my_sub is still what it was.
Note that this can be a security risk, but it may come in handy someday.
#!/usr/bin/perl -w
use strict;
sub my_sub {
print "This is the first subroutine called my_sub\n";
}
my $soft_sub = 'sub {
print "This is the redefined subroutine.\\n";
};';
my $my_sub = "The scalar with the same name.\n";
my $sub_ref;
eval "\$sub_ref = $soft_sub";
my_sub();
print "$my_sub\n";
undef &{ *my_sub{CODE} };
*my_sub = $sub_ref;
my_sub();
print $my_sub;