Wie wird der bedingte Operator ( ? :
) in Ruby verwendet?
Ist das zum Beispiel richtig?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Wie wird der bedingte Operator ( ? :
) in Ruby verwendet?
Ist das zum Beispiel richtig?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Antworten:
Es ist der ternäre Operator und funktioniert wie in C (die Klammern sind nicht erforderlich). Es ist ein Ausdruck, der funktioniert wie:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
In Ruby if
ist dies jedoch auch ein Ausdruck: if a then b else c end
=== a ? b : c
, mit Ausnahme von Vorrangproblemen . Beides sind Ausdrücke.
Beispiele:
puts (if 1 then 2 else 3 end) # => 2
puts 1 ? 2 : 3 # => 2
x = if 1 then 2 else 3 end
puts x # => 2
Beachten Sie, dass im ersten Fall Klammern erforderlich sind (andernfalls ist Ruby verwirrt, weil es denkt, dass es sich puts if 1
um zusätzlichen Müll handelt), im letzten Fall jedoch nicht, da das Problem nicht auftritt.
Sie können das "Long-If" -Formular zur besseren Lesbarkeit in mehreren Zeilen verwenden:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
und die einzigen falschen Werte false
. In der Tat nicht sehr üblich.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
mit Klammern. Andernfalls ist die Reihenfolge der Operationen nicht klar. Als ich dies zum ersten Mal las, war ich verwirrt, als ich es wie (puts true) ? "true" : "false"
erwartet las puts
, um den Booleschen Wert zurückzugeben, der dann zum Zeichenfolgenwert wurde.
Ihre Verwendung von ERB deutet darauf hin, dass Sie sich in Rails befinden. Wenn ja, dann ziehen Sie truncate
einen eingebauten Helfer in Betracht , der die Arbeit für Sie erledigt:
<% question = truncate(question, :length=>30) %>
@pst gab eine großartige Antwort, aber ich möchte erwähnen, dass in Ruby der ternäre Operator in einer Zeile geschrieben ist, um syntaktisch korrekt zu sein, im Gegensatz zu Perl und C, wo wir ihn in mehreren Zeilen schreiben können:
(true) ? 1 : 0
Normalerweise wird Ruby einen Fehler auslösen, wenn Sie versuchen, ihn auf mehrere Zeilen aufzuteilen. Sie können jedoch das \
Zeilenfortsetzungssymbol am Ende einer Zeile verwenden, und Ruby freut sich:
(true) \
? 1 \
: 0
Dies ist ein einfaches Beispiel, aber es kann sehr nützlich sein, wenn Sie mit längeren Zeilen arbeiten, da der Code übersichtlich bleibt.
Es ist auch möglich, das Ternär ohne die Zeilenfortsetzungszeichen zu verwenden, indem die Operatoren als letzte in die Zeile gesetzt werden, aber ich mag oder empfehle es nicht:
(true) ?
1 :
0
Ich denke, das führt zu sehr schwer lesbarem Code, da der bedingte Test und / oder die Ergebnisse länger werden.
Ich habe Kommentare gelesen, in denen es heißt, den ternären Operator nicht zu verwenden, weil er verwirrend ist, aber das ist ein schlechter Grund, etwas nicht zu verwenden. Nach der gleichen Logik sollten wir keine regulären Ausdrücke, Bereichsoperatoren (' ..
' und die scheinbar unbekannte "Flip-Flop" -Variante) verwenden. Sie sind mächtig, wenn sie richtig verwendet werden, daher sollten wir lernen, sie richtig zu verwenden.
Warum hast du Klammern gesetzt
true
?
Betrachten Sie das Beispiel des OP:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Durch das Umschließen des bedingten Tests wird die Lesbarkeit verbessert, da der Test visuell getrennt wird:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Natürlich könnte das gesamte Beispiel durch einige vernünftige Ergänzungen von Leerzeichen viel lesbarer gemacht werden. Dies ist nicht getestet, aber Sie werden auf die Idee kommen:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
Oder idiomatischer geschrieben:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Es wäre leicht zu argumentieren, dass die Lesbarkeit ebenfalls stark darunter leidet question.question
.
true
?
true
sitzt eigentlich für was wäre ein Ausdruck, der zu true
oder auswertet false
. Es ist besser, diese visuell abzugrenzen, da sich ternäre Anweisungen schnell in visuelles Rauschen verwandeln können, wodurch die Lesbarkeit verringert wird, was sich auf die Wartbarkeit auswirkt.
Ein einfaches Beispiel, bei dem der Bediener prüft, ob die ID des Spielers 1 ist, und die ID des Feindes abhängig vom Ergebnis festlegt
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
Und ich habe einen Beitrag zum Thema gefunden, der ziemlich hilfreich erscheint.
enemy_id = player_id == 1 ? 2 : 1
?
Der Code condition ? statement_A : statement_B
entspricht
if condition == true
statement_A
else
statement_B
end
Einfachster Weg:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
da param_a
ist nicht gleich param_b
dann wird der result
Wert von 'seinNot same!
question=question[0,20]
Wenn es kleiner als 20 wäre, würde es nichts daran ändern.