Perl одна строка, если заявление - PullRequest
12 голосов
/ 15 марта 2012

У меня есть заявление

$set eq "Y" ? $set = "N" : $set = "Y";

Но независимо от того, что всегда устанавливается на "N"

# Toggle setting
if ($set eq "Y")
{
   $set = "N";
}
else
{
   $set = "Y";
}

Почему один лайнер не работает?

Ответы [ 5 ]

26 голосов
/ 15 марта 2012

Из-за правил приоритета, perl не анализирует ваше утверждение, как вы думаете:

$ perl -MO=Deparse,-p -e '$set eq "Y" ? $set = "N" : $set = "Y"'
((($set eq 'Y') ? ($set = 'N') : $set) = 'Y');
-e syntax OK

Итак, как вы видите, в обоих условиях конечным результатом является скаляр $set, который затем устанавливается вY.

Вы можете исправить это несколькими скобками:

$set eq "Y" ? $set = "N" : ($set = "Y")

Но зачем повторять назначение:

$set = $set eq 'Y' ? 'N' : 'Y';
8 голосов
/ 15 марта 2012

Приоритет оператора.То, что вы написали, эквивалентно

($set eq "Y" ? $set = "N" : $set) = "Y";

Если вы настаиваете на написании такого краткого кода, это имеет больше смысла:

$set = ( $set eq "Y" ? "N" : "Y" );
7 голосов
/ 15 марта 2012
$set = ($set eq "Y") ? "N" : "Y";

должно работать

5 голосов
/ 15 марта 2012

Это о приоритете;давайте сделаем намерение с круглыми скобками, а затем позволим Perl удалить их снова:

perl -MO=Deparse -e '($set eq "Y") ? ($set = "N") : ($set = "Y"); print $set'
$set eq 'Y' ? $set = 'N' : ($set = 'Y');
print $set;
-e syntax OK

Что, таким образом, необходимо заключить в круглые скобки, как вы и хотели.

4 голосов
/ 06 декабря 2014

Если вы предпочитаете не использовать условные операторы в стиле "C", вы можете сделать то же самое с 2 строками:

my $set = "Y"; #Set the scope and default value
$set = "N" if ($set eq "Y");

Я лично рекомендую стиль "C", описанный другими выше ... он легко демонстрирует два варианта, которыми может быть переменная.

Однако метод, который я показываю, хорош при работе с одним условным результатом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...