Я хотел бы выполнить некоторую запутанную вариацию назначения @a = @b || @c
, намереваясь взять @b
, если он не пустой (следовательно, истинный в логическом смысле), @c
в противном случае. Документация явно говорит мне, что я не могу. (И это тоже верно!)
Операторы "||", "//" и "&&" возвращают последнее оцененное значение
(в отличие от C "||" и "&&", которые возвращают 0 или 1).
[...]
В частности, это означает, что вы не должны использовать это для выбора
между двумя агрегатами для назначения:
@a = @b || @c; # this is wrong
@a = scalar(@b) || @c; # really meant this
@a = @b ? @b : @c; # this works fine, though
К сожалению, на самом деле это не говорит мне, почему.
Я ожидал, что произойдет следующее:
@a =
- это присвоение массива, вызывающее контекст списка справа.
@b || @c
- правая часть, которая должна оцениваться в контексте списка.
||
- логическое короткое замыкание в стиле C или. Он оценивает слева направо (при необходимости) и распространяет контекст.
@b
оценивается в контексте списка. Если true (, т.е. , не пусто), оно возвращается.
- если нет,
@c
также вычисляется в контексте списка и возвращается.
Очевидно, мое предпоследнее утверждение неверно. Зачем? И, что более важно, какая часть документации или источников объясняет это поведение?
PS: из сферы действия вопроса я воздерживаюсь от предложенного в документации использования тернарного оператора, потому что мой @b
фактически является временным (результат вызова функции).