最近、私はリストの1秒おきの値を除外するためにこの方法に出くわしました:
perl -E 'say grep --$|, 1..10'
13579
それはどのように機能しますか?
$|
値0と 1 のみを持つことができる特別な Perl 変数です$|
。
$| = 1;$| = 'フー';$| = "4asdf"; # 0 + "4asdf" は 4 $| = \@a;
1に設定する効果があります。偽のゼロ値$|
の割り当て
$| = 0; $| = ""; $| = undef; $| = "エルク"; # 0 + "erk" は 0
$|
0に設定されます。
に展開--$|
すると$| = $| - 1
、何が起こっているかがわかります。$|
元が 1 だった場合は--$|
、値を 0 に変更します$|
。元が 0 だった場合は--$|
、値を -1 に設定しようとしますが、実際には値を 1 に設定します。
ハ! $|
"predecremented" の場合、ゼロ (perl では false) と 1 (true) の値の間で反転します。これらの値のみを保持できます。
したがって、grep
パスごとに基準が変化し、true、false、true、false などになり、リストの他のすべての要素が返されます。
半端なく賢すぎる。
ポイントは、この使用法は単なる厄介なハックであるということです。
$|
(または彼のより読みやすいエイリアス) は、 (または現在選択されているファイルハンドル)$OUTPUT_AUTOFLUSH
の自動フラッシュを制御するための特別な変数です。したがって、true ( ) または false ( )STDOUT
のみを受け入れます。1
0
$|
0 または 1 しか指定できません。デフォルトは0
であるため、0 番目のインデックスを -ing する前にデクリメントするとgrep
、1 になります。
その後のデクリメントは、実際には 0 から 1 へ、さらに 0 へと「トグル」します。