How does --$| work in Perl?
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 开发者_Go百科work?
$|
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.
The point is this use is just a nasty hack.
$|
( or his more readable alias $OUTPUT_AUTOFLUSH
) is a special variables to control the autoflush of STDOUT
( or the current selected filehandle). Therefore it only accepts true (1
) or false (0
).
精彩评论