Perl hat einen conditional Operator, der ein C's conditional operator ist.Sollte ich Perl bedingten verwenden? : operator als switch/case statement oder anstelle von elsif?
zu aktualisieren, der bedingten Operator in C und in Perl ist:
(test) ? (if test was true) : (if test was false)
und wenn sie mit einem L-Wert verwendet, können Sie zuweisen und Test mit einer Aktion:
my $x= $n==0 ? "n is 0" : "n is not 0";
Ich lese Igor Ostrovskys Blog auf A neat way to express multi-clause if statements in C-based languages und erkannte, dass dies auch in Perl ein "ordentlicher Weg" ist.
Zum Beispiel: (edit: verwendete Jonathan Leffler lesbare Form ...)
# 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
die viel einfacher als das, was viele schreiben würde in Perl liest: (edit: verwendet cjm die elegantere my $t=do{ if };
Form in rafis Antwort)
# 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!" }
};
Gibt es irgendwelche Probleme oder Nachteile hier? Warum würde ich auf diese Weise kein erweitertes bedingtes Formular schreiben, anstatt if(something) { this } elsif(something) { that }
zu verwenden?
Der bedingte Operator hat right associativity and low precedence. Also:
a ? b : c ? d : e ? f : g
wird interpretiert als:
a ? b : (c ? d : (e ? f : g))
Ich nehme an, Sie Klammer benötigen, wenn Sie Ihre Tests als ?:
einer der wenigen Betreiber niedrigere Priorität verwendet. Sie könnten auch Blöcke in das Formular mit Klammern setzen, denke ich.
Ich weiß über die veralteten use Switch
oder über given/when
Konstrukte Perl 5.10, und ich bin nicht auf der Suche für einen Vorschlag, diese zu nutzen.
Das sind meine Fragen:
Sie diese Syntax in Perl verwendet gesehen ** habe ich nicht, und es ist nicht in
perlop
oderperlsyn
als Alternative zu wechseln.Gibt es potentielle Syntaxprobleme oder "Gotchas" mit einem Bedingungs-/Ternäroperator auf diese Weise?
Meinung: Ist es für Sie besser verständlich? Entspricht es Idiomatic Perl?
-------- Bearbeiten -
Ich nahm Jonathan Leffler Antwort, weil er mich zu Perl Best Practices hingewiesen. Der relevante Abschnitt ist 6.17 auf Tabular Ternaries. Dies erlaubte mir, den Gebrauch weiter zu untersuchen. (Wenn Sie Google Perl Tabular Ternaries besuchen, können Sie weitere Kommentare sehen.)
Conways zwei Beispiele sind:
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"
;
Meine Schlussfolgerungen sind:
Conways
?:
Beispiel besser lesbar und einfacher zu mir ist, als dieif/elsif
Form, aber ich konnte sehen, wie die Form schwer zu verstehen sein könnte.Wenn Sie 5.13.1 haben Perl, verwenden
my $t=do { given { when } };
als Aufgabe als rafi has done. denke ichgiven/when
die beste Idiom jetzt ist, es sei denn, die tabellarische ternären Format besser für Ihren speziellen Fall ist.Wenn Sie Perl 5.10+ haben, verwenden Sie
given/when
im Allgemeinen anstelle vonSwitch
oder wenn Sie irgendeine Art von Falltyp-Schalter benötigen.Ältere Perls, dies ist eine feine Form für einfache Alternativen oder als Alternative zu einer Fallanweisung. Es ist besser als
Switch
ich denke.Die Assoziativität von rechts nach links bedeutet, dass das Formular von unten nach oben ausgewertet wird. Denken Sie daran, dass bei der Verwendung ...
Ich mag Ihre Formatierung für beide Alternativen besser, und die bedingte Form, die Sie immer noch leichter zu lesen als die if/elsif. Was denken Sie? – dawg
@drewk: Sie sind beide ziemlich lesbar; Das bedingte Operatorformular hat eine einzige Zuweisung, so dass klar ist, dass ein einzelner Wert zugewiesen wird, während bei der if-chain-Version eine der Aktionen "$ l =" something ";" und der Tippfehler im Variablennamen sein könnte könnte für eine Weile unpunktiert bleiben. Also, ja, ich denke, es gibt Vorteile für den bedingten Operator - aber es ist keine schrecklich starke Präferenz. –