Wednesday, October 27, 2010

Dynamic Perl Subroutines

You've got a set of subroutines that take similar numbers of parameters, but need to call a different constructor from different modules which use OO Perl. Here is an example of how that can be done using dynamic Perl subroutines.


---------- mod1.pm ----------
package mod1;

sub new
{
my ($modname,$a,$b) = @_;
print "In module 1\n";
return bless {'a'=>"$a","b"=>"$b"};
}

1;

---------- mod2.pm ----------
package mod2;

sub new
{
my ($modname,$a,$b) = @_;
print "In Module 2\n";
return bless {'a'=>"$a","b"=>"$b"};
}

1;


---------- main program -----
#!/usr/bin/perl

use mod1;
use mod2;

sub declared
{
my $module = shift;
# $cmd contains the code which will be the body of our subroutine
$cmd="my (\$name, \$fullname) = \@_; $module(\$name, \$fullname);";
# perform and evaluation on $cmd so that it becomes an anonymous subroutine reference
$cmd = eval("sub { $cmd };");
# return the subroutine reference (a normal Perl thing)
return $cmd;
};

# Create a subroutine reference that calls the new method from mod1
my $campus=declared("new mod1");
# Create a subroutine reference that calls the new method from mod2
my $camp=declared("new mod2");
# Now call the 2 subroutines from the different modules
my $f=&$campus("Module 1","blah blah");
my $g=&$camp("Module 2","more blah");
# Show that we did get different results from the 2 methods
print "f: ",$f->{a}," and ",$f->{b},"\n";
print "g: ",$g->{a}," and ",$g->{b},"\n";


What fun was that. Now you are all going to want to go away and reduce your code :-)

No comments:

Post a Comment