Странное взаимодействие между принтом и троичным условным оператором - PullRequest
1 голос
/ 20 февраля 2020

Натолкнулся на странное взаимодействие между print и троичным условным оператором, которое я не понимаю. Если мы сделаем ...:

print 'foo, ' . (1 ? 'yes' : 'no') . ' bar';

... тогда мы получим вывод ...:

foo, yes bar

. ... как мы и ожидали. Однако, если мы сделаем ...:

print (1 ? 'yes' : 'no') . ' bar';

... тогда мы просто получим вывод ...:

yes

Почему «бар» не добавляется к выводу во втором случае?

Ответы [ 2 ]

10 голосов
/ 20 февраля 2020

Давайте сделаем это, но на самом деле - то есть с предупреждениями на

perl -we'print (1 ? "yes" : "no") . " bar"'

Он печатает

print (...) interpreted as function at -e line 1.
Useless use of concatenation (.) or string in void context at -e line 1.
yes

(но без перевода строки в конце)

Так как (1 ? "yes" : "no") принимается в качестве списка аргументов для функции print, то троичное число оценивается как yes, и это аргумент для print, и, таким образом, один распечатаны. Поскольку это известная «ошибка», которая может быть легко сделана по ошибке, мы любезно получаем предупреждение за нее.

Затем строка " bar" объединяется (с возвращаемым значением print, которое это 1), что бессмысленно в пустом контексте, и за что мы также получаем предупреждение.

Один из обходных путей - добавить +, заставляя интерпретировать () как выражение

perl -we'print +(1 ? "yes" : "no") . " bar", "\n"'

Или, правильно вызвать print как функцию, с круглыми скобками

perl -we'print( (1 ? "yes" : "no") . " bar", "\n" )'

, где я добавил символ новой строки в обоих случаях.

См. этот пост для подробного обсуждения связанного примера и точных ссылок на документацию.

2 голосов
/ 20 февраля 2020

Если первый непробельный символ после имени функции является открывающей скобкой, то Perl будет интерпретировать это как начало списка параметров функции, а соответствующие закрывающие скобки будут использоваться как конец списка параметров. Это одна из вещей, о которой use warnings расскажет вам.

Обычное исправление - вставить + перед открывающей скобкой.

$ perl -e "print (1 ? 'yes' : 'no') . ' bar'"
yes
$ perl -e "print +(1 ? 'yes' : 'no') . ' bar'"
yes bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...