У меня есть инструкция
$set eq "Y" ? $set = "N" : $set = "Y";
Но независимо от того, что он всегда устанавливает в "N"
# Toggle setting
if ($set eq "Y")
{
$set = "N";
}
else
{
$set = "Y";
}
Почему не работает один лайнер?
У меня есть инструкция
$set eq "Y" ? $set = "N" : $set = "Y";
Но независимо от того, что он всегда устанавливает в "N"
# Toggle setting
if ($set eq "Y")
{
$set = "N";
}
else
{
$set = "Y";
}
Почему не работает один лайнер?
Из-за правил приоритета 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';
Приоритет оператора. То, что вы написали, эквивалентно
($set eq "Y" ? $set = "N" : $set) = "Y";
Если вы настаиваете на написании такого краткого кода, это имеет смысл:
$set = ( $set eq "Y" ? "N" : "Y" );
$set = ($set eq "Y") ? "N" : "Y";
должен работать
Это о приоритете; сделайте намерение с помощью скобок, а затем пусть 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
Который, таким образом, является скобкой, необходимой для выполнения, как вы планировали.
Если вы предпочитаете не использовать условные выражения стиля "C", вы можете сделать то же самое с двумя строками:
my $set = "Y"; #Set the scope and default value
$set = "N" if ($set eq "Y");
Я лично рекомендую стиль "С", описанный другими выше... он легко демонстрирует две опции, которые может быть переменной.
Тем не менее, метод, который я показываю, хорош при работе с одним условным результатом.