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.
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:
So I set a naming convention. Another product lets say foobar1_0 was a previous build and the current product is foobar2_0. The checkout or installer procedure might have changed between the two releases.
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()
{
}
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"
};
In the main build script we do the following:
//$project_prefix is a parameter. in our case "foobar1_0"
$curmapname = $project_prefix."_map"
//Notice %$curmapname is also a indirect reference.
//%cur_map is now a reference to %foobar1_0_map
%cur_map = %$curmapname
If the main project is built, we do not override %cur_map. But no matter what, we do a checkout by calling
&{$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