Recently I came across this way to filter out every second value of a list:
perl -E 'say grep --$|, 1..10'
13579
How does it work?
It is the smartmatch operator. In general, when you want information about operators in Perl, see perldoc perlop. Follow this answer to receive notifications.
Perl is a fairly straightforward, widely known and well-respected scripting language. It is used for a variety of tasks (for example, you can use it to create the equivalent of DOS batch files or C shell scripts), but in the context of Web development it is used to develop CGI scripts.
It's an operator. Specifically, the readline operator. There's a reference to it as the "angle operator" in perlvar, although there isn't actually any such operator.
$|
is a special Perl variable that can only have the values 0 and 1.
Any assignment to $|
of a true non-zero value, like
$| = 1;$| = 'foo';$| = "4asdf"; # 0 + "4asdf" is 4 $| = \@a;
will have the effect of setting $|
to 1. Any assignment of a false zero value
$| = 0; $| = ""; $| = undef; $| = "erk"; # 0 + "erk" is 0
will set $|
to 0.
Expand --$|
to $| = $| - 1
, and now you can see what is going on.
If $|
was originally 1, then --$|
will change the value to 0.
If $|
was originally 0, then --$|
will try to set the value to -1 but will actually set the value to 1.
Ha! $|
flips between the values of zero (false, in perl) and one (true) when "predecremented" -- it can only hold those values.
So, your grep
criterion changes on each pass, going true, false, true, false, etc., and so returning every other element of the list.
Too clever by half.
$|
can only be zero or one. The default is 0
, so by decrementing it before grep
-ing the 0th index, it'll be one.
The subsequent decrements will actually "toggle" it from zero to one to zero and so forth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With