Reputation: 365
Yesterday I wrote a little subroutine to parse my /etc/hosts file and get the hostnames from it.
This is the subroutine:
sub getnames {
my ($faculty, $hostfile) = @_;
open my $hosts ,'<', $hostfile;
my @allhosts = <$hosts>;
my $criteria = "mgmt." . $faculty;
my @hosts = map {my ($ip, $name) = split; $name} grep {/$criteria/} @allhosts; # <-this line is the question
return @hosts;
}
I called it like getnames('foo','/etc/hosts')
and got back the hostnames that match the mgmt.foo
regex.
The question is, why do I have to write $name
alone in the map
expression? If I don't write it, get back the whole line. Does the variable evaluate to its value?
Upvotes: 2
Views: 244
Reputation: 139431
The list-context result from map
is a concatenation of all the results of evaluating your block for each matching host. Remember that the return value from a block is the value of the last expression evaluated, whether or not your code incants an explicit return
. Without the final $name
, the last expression—and thus the block’s return value—is the result from split
.
Another way to write it is
my @hosts = map {(split)[1]} grep {/$criteria/} @allhosts;
You could fuse the map
and grep
to get
my @hosts = map { /$criteria/ ? (split)[1] : () } @allhosts;
That is, if a given host meets your criteria, then split it. Otherwise, there is no result for that host.
Upvotes: 8