How do I pass a function to Perl?
How do I write a function that takes something like a map function?
Example:
$func = sub { print $_[0], "hi\n" };
&something($f);
sub something
{
my $func = shift;
for ($i = 0; $i < 5; $i++)
{ $func->($i); }
}
works great.
but if i did
&something( { print $_[0], "hi\n" } );
it doesn't work and says func is an undefined reference.
So my question is how to write a function that takes parameters like the pearls map function?
map { s/a/b/g } @somelist;
source to share
The function map
has a very magical syntax, and you probably don't want to copy it unless you have a really good reason; just use a regular anonymous sub, like this:
something(sub { print $_[0], "hi\n" });
If you really want to do this, you need to use prototype :
sub my_map (&@) {
my ($func, @values) = @_;
my @ret;
for (@values) {
push @ret, $func->($_);
}
return @ret;
}
my @values = my_map { $_ + 1 } qw(1 2 3 4);
print "@values"; # 2 3 4 5
(Note that it is $_
dynamically constrained, so whatever value it has in the caller is stored in the function.)
List::Util
and List::MoreUtils
do it something special to create functions that look inline and act like variants of map
/ grep
. This is really the only time you need to use something like this.
source to share
First of all, don't use &
when calling sub
s. From perldoc perlsub
:
Subroutines can be named recursively. If the subroutine is called using the form
&
, the argument list is optional, and if omitted, no array is set for the subroutine@_
: the array@_
is visible to the subroutine at the time of the call instead of.This is an efficiency mechanism that new users may want.
If you want to pass a simple block to " sub something
", you need to use a prototype, as in:
sub something(&@);
# later
sub something(&@) {
my ($coderef, @args) = @_;
}
See Prototypes .
I personally would just pass an explicit subref:
something( sub { } );
source to share