Скалярный против контекста списка - PullRequest
0 голосов
/ 14 января 2019

Интересно, каково обоснование следующих двух примеров, дающих разные результаты, когда в обоих случаях do {} возвращает списки.

perl -wE 'say my $r = do {  (44); }'
44

perl -wE 'say my $r = do {  my ($x) = map $_, 44; }'
1

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Прежде всего, ни do не возвращает список. Они оцениваются в скалярном контексте, поэтому они должны возвращать один скаляр, а не произвольное количество скаляров («список»).

В первом случае do возвращает результат оценки 44 в скалярном контексте. Это возвращает 44.

scalar(    44    ) ⇒ 44

Во втором случае do возвращает результат оценки назначения списка в скалярном контексте. Возвращает количество элементов, возвращаемых правой частью присваивания.

scalar(    () = 44    ) ⇒ 1

Я полагаю, что истинная причина вашего замешательства в том, что вы не знаете об операторах присваивания и о том, как на них влияет контекст. Если это так, см. Скалярный оператор сравнения списков для ответа на ваш реальный вопрос.

0 голосов
/ 14 января 2019

В обоих случаях присваивание $ r вызывает скалярный контекст в do. Однако в первом случае скалярный контекст в списке возвращает последнее значение списка, «44».

Во втором случае присваивание my ($x) вызывает контекст списка. Результатом присваивания списку в скалярном контексте является количество элементов в правой части присвоения. Итак, вы получите.

map $_, 44 возвращает список длины 1, содержащий (44)

my ($x) = присваивает приведенные выше результаты в контексте списка из-за скобок вокруг $x списку ($x), составляющему $ x = 44

Блок do находится в скалярном контексте из-за присваивания $r, обратите внимание на отсутствие скобок, и, как я уже говорил выше, это возвращает длину правой части назначения списка. 1 в этом случае.

Посмотрите, что произойдет, если вы сделаете это:

perl -wE 'say my $r = () = (1,3,5,7)'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...