Skip to content
Subroutine References and map/grep
step 1/5

Reading — step 1 of 5

Learn

~1 min readReferences and Structures

Subroutines are first-class. Take a reference with \&name, dereference with ->():

sub greet { return "Hello, $_[0]"; }
my $g = \&greet;
print $g->("Ada"), "\n";

Anonymous subs with sub { ... }:

my $square = sub { $_[0] ** 2 };
print $square->(5);   # 25

map and grep are built-in transformations. Both take a block (or expression) and a list:

my @nums = (1, 2, 3, 4, 5);

# Square each
my @squared = map { $_ ** 2 } @nums;        # (1, 4, 9, 16, 25)

# Keep evens
my @evens = grep { $_ % 2 == 0 } @nums;     # (2, 4)

# Chain: sum of even squares
my $sum = 0;
$sum += $_ for grep { $_ % 2 == 0 } map { $_ ** 2 } @nums;

In the block, $_ is the current element. map returns a list of transformed values; grep returns a list of items for which the block is true.

sort with a comparator:

my @sorted = sort { $a <=> $b } @nums;       # numeric ascending
my @desc = sort { $b <=> $a } @nums;          # numeric descending
my @by_age = sort { $a->{age} <=> $b->{age} } @users;

In sort's block, $a and $b are the two items being compared. <=> is numeric compare; cmp is string compare.

reduce is in List::Util:

use List::Util qw(sum max min reduce);
my $total = sum @nums;
my $product = reduce { $a * $b } @nums;

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…