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;

      

+2


source to share


3 answers


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.

+17


source


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 { } );

      

+6


source


&something( { print $_[0], "hi\n" } );
#           ^^^ this isn't a reference

&something( sub { print $_[0], "hi\n" } ); # works just fine

      

+1


source







All Articles