Как это сделать - $ | работать в Perl? - PullRequest
20 голосов
/ 10 февраля 2011

Недавно я сталкивался с таким способом отфильтровывать каждое второе значение списка:

perl -E 'say grep --$|, 1..10'
13579

Как это работает?

Ответы [ 4 ]

25 голосов
/ 10 февраля 2011

$| - это специальная переменная Perl, которая может иметь только значения 0 и 1. Любое присвоение $| true ненулевого значения, например

$| = 1;
<strike>$| = 'foo';</strike>
$| = "4asdf";          # 0 + "4asdf" is 4
$| = \@a;

будет иметь значение установки $| в 1. Любое назначение false нулевое значение

$| = 0;
$| = "";
$| = undef;
$| = "erk";            # 0 + "erk" is 0

установит $| в 0.

Развернуть--$| до $| = $| - 1, и теперь вы можете видеть, что происходит.Если $| изначально было 1, то --$| изменит значение на 0. Если $| изначально было 0, то --$| попытается установить значение -1, но фактически установит значение 1.

6 голосов
/ 10 февраля 2011

Ха! $| переключается между значениями ноль (ложь, в perl) и единица (истина), когда "предварительно задано" - оно может содержать только эти значения.

Таким образом, ваш критерий grep меняется при каждом проходе, происходит истина, ложь, истина, ложь и т. Д., И, таким образом, возвращаются все остальные элементы списка.

Слишком умный наполовину.

3 голосов
/ 10 февраля 2011

Суть в том, что это использование - просто мерзкий взлом.
$| (или его более читаемый псевдоним $OUTPUT_AUTOFLUSH) - это специальные переменные для управления автоматическим сбросом STDOUT (или текущей выбранной файловой ручки). Следовательно, он принимает только истину (1) или ложь (0).

3 голосов
/ 10 февраля 2011

$| может быть только ноль или единица. По умолчанию используется значение 0, поэтому, уменьшив его до значения grep, равного 0-му индексу, он будет равен единице.

Последующие декременты фактически «переключат» его с нуля на единицу на ноль и т. Д.

...