Может ли пустой список находиться в скалярном контексте? - PullRequest
5 голосов
/ 06 августа 2011

Существует ложь, что список в скалярном контексте дает последний элемент списка. Это ложь, потому что (как говорится) у вас не может быть списка в скалярном контексте. То, что выглядит как список в скалярном контексте, на самом деле является оператором запятой в скалярном контексте, и в скалярном контексте он имеет другое поведение.

Однако в этой логике, похоже, есть дыра в петле: нулевой список (иногда называемый пустым списком). Символы () определены как нулевой список perldoc perlglossary. Конструкция

my $s = ();

является действительным кодом и возвращает undef в $s. Кажется, это не документировано нигде в perldoc (я не проверял верблюда), но на него рассчитывает много кода, поэтому я думаю, что он останется здесь.

Теперь, когда преамбула выполнена, возникает вопрос: если у нас не может быть списка в скалярном контексте, то, что мы называем пустым списком в скалярном контексте, и что является разумным, чтобы не называть его списком (поскольку нет запятых в скалярном контексте)?

Если вам нравится этот вопрос, вам также может понравиться обсуждение , проходящее в P5P .

Ответы [ 2 ]

7 голосов
/ 07 августа 2011

Список - это очень общее слово. Возможно, вы имеете в виду оператор списка или значение списка.

В коде нет запятой, поэтому оператор списка отсутствует.

В коде отсутствует контекст списка, поэтому нет значения списка.

Следовательно, в

нет списка
my $s = ();

Скобки никогда не создают список

(Только косвенно, когда на LHS оператора присваивания.)

что мы называем пустым списком в скалярном контексте

Perl называет это «заглушкой» (как показано ниже), и это действительно так. Это заполнитель в коде, где буквально ничего не будет запрещено.

Заглушка представлена ​​«пустыми скобками», так что это другое название для нее.

Я называю это плохим кодом. Если вы хотите присвоить undef, присвойте undef.

Существует ложь, что список в скалярном контексте дает последний элемент списка.

Нет, это правда. Значения списка не могут существовать в скалярном контексте, поэтому остается оператор списка.

Оператор списка, или оператор запятой, возвращает последний элемент списка в скалярном контексте.


Сравните следующее. Нет упоминания о списке:

>perl -MO=Concise -e"my $s = ();"
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
5     <2> sassign vKS/2 ->6
3        <0> stub sP ->4
4        <0> padsv[$s:1,2] sRM*/LVINTRO ->5
-e syntax OK

Есть упоминание о списке

>perl -MO=Concise -e"my @a = ();"
7  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
6     <2> aassign[t2] vKS ->7
-        <1> ex-list lK ->4
3           <0> pushmark s ->4
-           <0> stub lP ->-
-        <1> ex-list lK ->6
4           <0> pushmark s ->5
5           <0> padav[@a:1,2] lRM*/LVINTRO ->6
-e syntax OK

... и это не имеет никакого отношения к паренсу

>perl -MO=Concise -e"my @a = 's';"
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
7     <2> aassign[t2] vKS ->8
-        <1> ex-list lK ->5
3           <0> pushmark s ->4
4           <$> const[PV "s"] s ->5
-        <1> ex-list lK ->7
5           <0> pushmark s ->6
6           <0> padav[@a:1,2] lRM*/LVINTRO ->7
-e syntax OK
1 голос
/ 07 августа 2011

Это больше похоже на бесполезное выражение, эквивалентное undef.Еще несколько примеров:

$ perl -we 'print scalar( () )'
Use of uninitialized value in print at -e line 1.

$ perl -we 'print 0+()'
Use of uninitialized value in addition (+) at -e line 1.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...