Perl имеет условный оператор , который аналогичен условному оператору C .
Чтобы обновить, условный оператор в C и Perl:
(test) ? (if test was true) : (if test was false)
, и если он используется с lvalue, вы можете назначить и протестировать его одним действием:
my $x= $n==0 ? "n is 0" : "n is not 0";
Я читал Игоря Островского ' Блог на Изящный способ выразить операторы if с несколькими предложениями в языках на основе C и понял, что это действительно «изящный способ» и в Perl.
Например: (edit: использовал более читаемую форму Джонатана Леффлера ...)
# ternary conditional form of if / elsif construct:
my $s=
$n == 0 ? "$n ain't squawt"
: $n == 1 ? "$n is not a lot"
: $n < 100 ? "$n is more than 1..."
: $n < 1000 ? "$n is in triple digits"
: "Wow! $n is thousands!" ; #default
Что читается НАМНОГО легче, чем то, что многие писали бы на Perl:
(править: использовалась более элегантная форма cjm my $ t = do {if};
в ответе Рафи)
# Perl form, not using Switch or given / when
my $t = do {
if ($n == 0) { "$n ain't squawt" }
elsif ($n == 1) { "$n is not a lot" }
elsif ($n < 100) { "$n is more than 1..." }
elsif ($n < 1000) { "$n is in triple digits" }
else { "Wow! $n is thousands!" }
};
Есть ли здесь какие-либо подводные камни или недостатки? Почему бы мне не написать расширенную условную форму таким образом, а не использовать if (something) {this} elsif (something) {that}
?
Условный оператор имеет правую ассоциативность и низкий приоритет . Итак:
a ? b : c ? d : e ? f : g
интерпретируется как:
a ? b : (c ? d : (e ? f : g))
Я полагаю, вам могут понадобиться скобки, если ваши тесты использовали один из немногих операторов с более низким приоритетом, чем ?:
. Я думаю, вы также можете поместить блоки в форму с помощью скобок.
Я знаю об устаревшем use Switch
или о конструкциях given / when
Perl 5.10, и я не ищу предложения по их использованию.
Эти мои вопросы:
Вы видели этот синтаксис, используемый в Perl? ** Я не видел, и его нет в perlop
или perlsyn
в качестве альтернативы для переключения.
Есть ли потенциал проблемы с синтаксисом или "подводные камни" при таком использовании условного / тернарного оператора?
Мнение: Вам он более читается / понятен? Совместимо ли это с идиоматическим Perl?
-------- Edit -
Я принял ответ Джонатана Леффлера, потому что он указал мне на Perl Best Practices . Соответствующий раздел - 6.17 на Табличные троичные. Это позволило мне продолжить исследование использования. (Если вы Google Perl Tabular Ternaries, вы можете увидеть и другие комментарии.)
Два примера Конвея:
my $salute;
if ($name eq $EMPTY_STR) {
$salute = 'Dear Customer';
}
elsif ($name =~ m/\A ((?:Sir|Dame) \s+ \S+)/xms) {
$salute = "Dear $1";
}
elsif ($name =~ m/([^\n]*), \s+ Ph[.]?D \z/xms) {
$sa1ute = "Dear Dr $1";
}
else {
$salute = "Dear $name";
}
VS:
# Name format... # Salutation...
my $salute = $name eq $EMPTY_STR ? 'Dear Customer'
: $name =~ m/ \A((?:Sir|Dame) \s+ \S+) /xms ? "Dear $1"
: $name =~ m/ (.*), \s+ Ph[.]?D \z /xms ? "Dear Dr $1"
: "Dear $name"
;
Мои выводы:
Конвей ?: Пример
для меня более читабелен и проще, чем форма if / elsif
, но я мог видеть, как форма может стать трудной для понимания.
Если у вас Perl 5.13.1, используйте my $ t = do {given {when}};
в качестве назначения, как это сделал rafi. Я думаю, что given / when
- лучшая идиома сейчас, если только табличный тернарный формат не подходит для вашего конкретного случая.
Если у вас Perl 5.10+, используйте given / when
в целом вместо Switch
или если вам нужен какой-то переключатель типа case.
Более старые Perl, это прекрасная форма для простых альтернатив или как альтернатива оператору case. Думаю, это лучше, чем использовать Switch
.
Ассоциативность справа налево означает, что форма оценивается снизу вверх. Помните, что при использовании ...