it-swarm.com.de

Wie verwende ich den bedingten Operator (? :) in Ruby?

Wie wird der bedingte Operator (? :) in Ruby verwendet?

Ist dies beispielsweise richtig?

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
270

Es ist der ternäre Operator und funktioniert wie in C (die Klammern sind nicht erforderlich). Es ist ein Ausdruck, der wie folgt funktioniert:

if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this

In Ruby ist if jedoch auch ein Ausdruck, also: if a then b else c end === a ? b : c, mit Ausnahme von Prioritätsproblemen. 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 er der Meinung ist, dass es puts if 1 mit etwas zusätzlichem Müll ist), aber im letzten Fall sind sie nicht erforderlich, da das Problem nicht auftritt.

Sie können das "long-if" -Formular für die Lesbarkeit in mehreren Zeilen verwenden:

question = if question.size > 20 then
  question.slice(0, 20) + "..."
else 
  question
end
452
user166390
puts true ? "true" : "false"
=> "true"


puts false ? "true" : "false"
=> "false"
31
DGM

Ihre Verwendung von ERB legt nahe, dass Sie sich in Rails befinden. Wenn ja, dann betrachten Sie truncate , einen integrierten Helfer, der die Arbeit für Sie erledigt:

<% question = truncate(question, :length=>30) %>
25
Wayne Conrad

@pst gab eine großartige Antwort, aber ich möchte erwähnen, dass in Ruby der ternäre Operator in eine Zeile geschrieben wird, um syntaktisch korrekt zu sein, im Gegensatz zu Perl und C, wo wir ihn in mehrere Zeilen schreiben können:

(true) ? 1 : 0

Normalerweise gibt Ruby einen Fehler aus, wenn Sie versuchen, es auf mehrere Zeilen aufzuteilen. Sie können jedoch das \-Zeilenfortsetzungssymbol am Ende einer Zeile verwenden. Ruby ist zufrieden:

(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 schön angeordnet ist.

Es ist auch möglich, das Ternary ohne die Zeilenfortsetzungszeichen zu verwenden, indem die Operatoren als letzte Zeile in der Zeile stehen, aber ich mag oder empfehle es nicht:

(true) ?
  1 :
  0

Ich denke, das führt zu wirklich schwer zu lesendem Code, da der bedingte Test und/oder die Ergebnisse länger werden.

Ich habe Kommentare gelesen, die besagen, dass der ternäre Operator nicht verwendet werden sollte, weil er verwirrend ist. 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 eingesetzt werden. Daher sollten wir lernen, sie richtig anzuwenden.


Warum haben Sie Klammern um true gesetzt?

Betrachten Sie das Beispiel des OP:

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

Das Umschließen des Bedingungs-Tests trägt dazu bei, den Test lesbarer zu machen, da er den Test visuell trennt:

<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>

Natürlich kann das gesamte Beispiel durch die Verwendung einiger sinnvoller Whitespace-Erweiterungen deutlich lesbarer gemacht werden. Dies ist nicht getestet, aber Sie bekommen die Idee:

<% 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 ist leicht zu argumentieren, dass die Lesbarkeit auch unter question.question leidet.

17
the Tin Man

Ein einfaches Beispiel, bei dem der Bediener überprüft, ob die ID des Spielers 1 ist, und abhängig vom Ergebnis die Feind-ID festlegt

player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2

Und ich habe ein post zu dem Thema gefunden, was ziemlich hilfreich erscheint.

3
devwanderer

Eine kleine Variante davon ist die Konvertierung in Boolean !! Betreiber wie dieser

result = !!(condition == true)
0
jcpennypincher

Der Code condition ? statement_A : statement_B ist äquivalent zu 

if condition == true
  statement_A
else
  statement_B
end
0
Umesh Malhotra