Подтвердить что ты не робот

Назначение внутри тернарных проблем операторского оператора Perl

Этот фрагмент кода Perl в моей программе дает неправильный результат.

$condition ? $a = 2 : $a = 3 ;
print $a;

Независимо от значения $condition, выход всегда равен 3, как получилось?

4b9b3361

Ответ 1

Это объясняется в документации Perl .

Из-за приоритета оператора Perl оператор анализируется как

($condition ? $a= 2 : $a ) = 3 ;

Поскольку оператор?: дает присваиваемый результат, 3 присваивается результат условия.

Когда $condition истинно, это означает ($ a = 2) = 3, давая $a = 3

Когда $condition является ложным, это означает ($ a) = 3, давая $a = 3

Правильный способ написать это

$a = ( $condition ? 2 : 3 );
print $a;

Мы были укушены этим на работе, поэтому я размещаю здесь, надеясь, что другие найдут это полезным.

Ответ 2

Как только у вас есть подозрение, что вы можете страдать от проблем с приоритетом, трюк, чтобы понять, что, по мнению Перла, вы имели в виду:

perl -MO=Deparse,-p -e '$condition ? $a= 2 : $a= 3 ; print $a;'

В вашем случае это покажет вам:

(($condition ? ($a = 2) : $a) = 3);
print($a);
-e syntax OK

... в этот момент вы должны сказать "о, это объясняет"!

Ответ 3

Просто чтобы продлить предыдущий ответ... Если по какой-либо причине назначения должны быть частью условного выражения, вы должны написать его следующим образом:

$condition ? ($a=2) : ($a=3);

Это было бы полезно, если бы вы назначали разные переменные на основе условия.

$condition ? ($a=2) : ($b=3);

И если вы выберете переменную, но при этом присвоите одно и то же, независимо от того, что вы могли бы сделать:

($condition ? $a : $b) = 3;

Ответ 4

Из-за приоритета оператора Perl оператор анализируется как:

($condition ? $a = 2 : $a ) = 3 ;

Поскольку оператор?: дает присваиваемый результат, 3 присваивается результат условия.

Когда $condition истинно, это означает, что $a = 2 = 3 дает $a = 3

Когда $condition является ложным, это означает, что $a = 3 дает $a = 3

Правильный способ написать это

$a = $condition ? 2 : 3;

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

Хорошее эмпирическое правило состоит в том, что условные выражения относятся только к простым значениям, а не к выражениям с побочными эффектами. Когда вам или кому-то еще нужно прочитать этот код через восемь месяцев, вы бы предпочли, чтобы он читал вот так?

$x < 3 ? foo($x) : bar($y);

Или как это?

if ($x < 3) {
  $foo($x);
} else {
  $bar($y);
}

Ответ 5

Одно предложение Титония ответить выше:

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

$a = (условие $)? 2: 3;