next if $seen{ $elem }++;
"Skip to the next iteration of the loop if $seen{ $elem } is true, otherwise make $seen{ $elem } true and continue."
Check out the segment on the unary '++' operator in perlop. When the operator follows a variable, it is incremented after its evaluation. In other words, in the above code, if checks the value of $seen{ $elem } before incrementing it. Since the action "next" is taken before the increment happens, the increment is skipped. Here's longer (and probably slightly slower) equivalent code:
if ( $seen{ $elem } ) {
next; # skip to the next loop iteration
}
else {
$seen{ $elem } += 1;
}
This is a common pattern that checks if you've encountered $elem before. If you have, it will not process it a second time; otherwise, it will mark $elem so that you won't process it again.
This could be used to get all the unique lines from a file, for example.
use strict;
use warnings;
open my $IN, '<', $ARGV[0] or die("Can't read $ARGV[0]: $!");
open my $OUT, '<', $ARGV[1] or die("Can't write $ARGV[1]: $!");
my %seen;
while (<$IN>) {
next if $seen{$_}++; # check/mark line as seen
print $OUT $_;
}
close $IN; close $OUT;
Or, even shorter while loop:
while (<$IN>) { $seen{$_}++ || print $OUT $_ }
|