Håkon Hægland
Håkon Hægland

Reputation: 40718

Anonymous hash in perl

I am starting to learn Perl, so I am trying to read some posts here at SO. Now I came across this code https://stackoverflow.com/a/22310773/2173773 (simplified somewhat here) :

echo "1 2 3 4" | perl -lane'
  $h{@F} ||= [];
  print $_ for keys %h;
'

What does this code do, and why does this code print 4?

I have tried to study Perl references at http://perldoc.perl.org/perlreftut.html , but I still could not figure this out.

(I am puzzled about this line: $h{@F} ||= [].. )

Upvotes: 1

Views: 125

Answers (1)

jwodder
jwodder

Reputation: 57470

  • The -n option (part of -lane) causes Perl to execute the given code for each individual line of input.
  • The -a option (when used with the -n or -p option) causes Perl to split every line of input on whitespace and store the fields in the @F variable.
  • $something ||= [] is equivalent to $something = $something || []; i.e., it assigns [] (a reference to an empty array) to the variable $something if & only if $something is already false or undefined.
  • $h{@F} is an element of the hash %h. Because this expression begins with $ (rather than @), the subscript @F is evaluated in scalar context, and scalar context for an array makes the array evaluate to its length. As the Perl code is only ever executed on the line 1 2 3 4, which is split into four elements, @F will only be four elements long, so $h{@F} is here equivalent to $h{4} (or, technically, $h{"4"}).

Thus, [] will be assigned to $h{"4"}, and as 4 is the only element of the hash %h in existence, keys %h will return a list containing only "4", and printing the elements of this list will print 4.

Upvotes: 5

Related Questions