Perl Tutorial: Function Pointers
In C the function pointer is how to passing functions around. In Perl using an ampersand in front of a string is treated an a function call.
Using this technique, I was able to override functions based on the product I was building.
For the current default product I has a series of calls to perform a build. Some might be:
The current script will build foobar2_0 by default. But when foobar1_0 requires a patch release, a build has to be done using the old checkout and installer procedures.
I define a library foobar1_0.pm for the foobar1_0 build rules:
&{$cur_map{checkout}}();
The truth is, I even allow main to be overridden. Yes, in my perl code I usually define a main() function.
So, function pointers are alive an well in Perl.
Note: You can not use strict to do this coding. If someone finds a way, I'd love to update this posting.
sub foo { print "called foo\n"; }
our $functname = "foo";
&{$funcname}();
Using this technique, I was able to override functions based on the product I was building.
For the current default product I has a series of calls to perform a build. Some might be:
- checkout
- installer
The current script will build foobar2_0 by default. But when foobar1_0 requires a patch release, a build has to be done using the old checkout and installer procedures.
I define a library foobar1_0.pm for the foobar1_0 build rules:
sub foobar1_0_checkout()In the main build script we do the following:
{
}
sub foobar1_0_installer()
{
}
//we are defining overrides for checkout and installer,
// but like build, nothing else is overridden. e.x in the full code, there are
// about 40 definitions of function and global variables.
//NOP is a No op function for functions that are not to be run.
%foobar1_0_map = {
# variables that need to be set
"checkout"=> "foobar1_0_checkout",
"installer"=> "foobar1_0_installer",
"make_test" => "NOP"
"build"=>"build"
};
//$project_prefix is a parameter. in our case "foobar1_0"If the main project is built, we do not override %cur_map. But no matter what, we do a checkout by calling
$curmapname = $project_prefix."_map"
//Notice %$curmapname is also a indirect reference.
//%cur_map is now a reference to %foobar1_0_map
%cur_map = %$curmapname
&{$cur_map{checkout}}();
The truth is, I even allow main to be overridden. Yes, in my perl code I usually define a main() function.
So, function pointers are alive an well in Perl.
Note: You can not use strict to do this coding. If someone finds a way, I'd love to update this posting.
Labels: function pointer, perl, tutorial

3 Comments:
Does this work if use strict is on? I get an error saying I can't use a string as a HASH ref while "strict refs" in use at ... Is this normal or am I doing something wrong?
By
Kymnyth, at 4:21 PM
Yes. That module does not use strict. The added functionality was worth it.
I think there is a way around it. But I have not dealt with it.
By
Mike, at 4:25 PM
Does this achieve the same end?
#!/usr/bin/perl -w
use strict;
sub One($) {
printf "one %s\n", @_;
}
sub Two($) {
printf "two %s\n", @_;
}
my %functionHash = (
'uno' => \&One,
'duo' => \&Two
);
$functionHash{'uno'}("potato");
$functionHash{'duo'}("potato");
By
Chris Reece, at 8:44 PM
Post a Comment
Links to this post:
Create a Link
<< Home