Greg Hewgill Greg Hewgill - 1 month ago 6
Perl Question

How can I distinguish $_ in nested list operators in Perl?

It is often useful to implement algorithms using nested array operations. For example, to find the number of words in a list that start with each given character, you might do something like this in Python:

>>> a = ["foo","bar","baz"]
>>> map(lambda c: len(filter(lambda w: w.startswith(c), a)), ('a','b','c','d','e','f'))
[0, 2, 0, 0, 0, 1]


In the expression
w.startswith(c)
it is trivial to distinguish between the two loop iteration variables
w
and
c
because they have different names.

In Perl, I would like to do something like this:

@a = ("foo", "bar", "baz");
map length(grep $_ =~ /^$_/, @a), ('a','b','c','d','e','f')


However, the obvious problem with this is that
$_
refers only to the innermost
grep
iteration variable (suitable for the
$_
on the left), not the one for the outer
map
(suitable for the
/^$_/
). What is the idiomatic way to avoid this problem in Perl?

Answer

Just assign to local variable:

@a = qw(foo bar baz);
map {my $ch = $_; scalar grep $_ =~ /^$ch/, @a} qw(a b c d e f)