Ruby ternärer Operator ohne sonst

78

Gibt es eine Rubinsprache für "If do-this" und "do-this" nur als einfachen Befehl?

Zum Beispiel mache ich gerade

object.method ? a.action : nil

um die else-Klausel leer zu lassen, aber ich denke, es gibt wahrscheinlich einen idiomatischeren Weg, dies zu tun, bei dem am Ende keine Null angegeben werden muss. (und alternativ denke ich, dass es in diesem Fall verschwenderisch wäre, mehrere Codezeilen zu verwenden.

RyanCacophony
quelle
Es hängt vom Kontext ab, aber manchmal ist es eleganter, einen if / while / begin-Block mit nur einer Zeile im Körper zu lesen als etwas dichteres / knapperes.
Glenn Jackman

Antworten:

113
a.action if object.method?
Greg Campbell
quelle
139

In der Regel: Sie benötigen den ternären Operator in Ruby so gut wie nie. Der Grund , warum Sie es in C benötigen, liegt daran , dass in C ist ifeine Aussage, wenn Sie also einen Wert , den Sie zurückkehren wollen haben den ternären Operator zu verwenden, was ein Ausdruck ist.

In Ruby ist alles ein Ausdruck, es gibt keine Anweisungen, was den ternären Operator ziemlich überflüssig macht. Sie können jederzeit ersetzen

cond ? then_branch : else_branch

mit

if cond then then_branch else else_branch end

Also, in Ihrem Beispiel:

object.method ? a.action : nil

ist äquivalent zu

if object.method then a.action end

was, wie @Greg Campbell betont, wiederum der nachfolgenden ifModifikatorform entspricht

a.action if object.method

Da die booleschen Operatoren in Ruby nicht nur trueoder false, sondern den Wert des zuletzt ausgewerteten Ausdrucks zurückgeben, können Sie sie auch für den Steuerungsfluss verwenden. Dies ist eine aus Perl importierte Redewendung, die folgendermaßen aussehen würde:

object.method and a.action
Jörg W Mittag
quelle
13
Dies ist eine großartige Antwort!
Tim Hettler
7
Der ternäre Operator cond ? a : bist kürzer als if cond then a else b end, das allein bringt mich dazu, 11 Zeichen zu sparen ;-)
Markus
1
Im Ruby Style Guide heißt es: "Bevorzugen Sie den ternären Operator ( ?:) gegenüber if/then/else/endKonstrukten. Er ist häufiger und offensichtlich prägnanter."
Kurt Bourbaki
18

Gregs Antwort ist die beste, aber für die Aufzeichnung und noch mehr als in C sind Ausdrücke und Aussagen in Ruby gleichwertig, sodass a.action if o.m?Sie außerdem Dinge tun können wie:

object.method? && a.action

Du kannst schreiben (a; b; c) if doder sogar

(a
 b
 c
) if d

oder für diese Angelegenheit: (x; y; z) ? (a; b c) : (d; e; f)

In Ruby gibt es keine Situation, in der nur eine einzige Anweisung oder ein Ausdruck zulässig ist ...

DigitalRoss
quelle
3

result = (<expression> && <true value>) || <false value>

value = 1 result = (value == 1 && 'one' ) || 'two' result #=> 'one' Erklären Sie: value == 1 && 'one' # => gibt das Ergebnis des letzten Ausdrucks zurück, value ist gleich 1, und der Abschnitt wird ausgewertet und 'one' zurückgegeben.

value = 0 result = (value == 1 && 'one' ) || 'two' result #=> 'two'

Erklären Sie: value! = 1 und 'und' Ausdruck werden nicht ausgewertet, aber instad wird verwendet 'oder' Ausdruck und es wird 'zwei' zurückgegeben.

Omakoleg
quelle
1

Eine andere Möglichkeit, dies in derselben Zeile zu tun, ist:

if object.method; a.action end

Dies wird von Rubocop als schlechter Stil angesehen, da es ein Semikolon verwendet, um den Ausdruck zu beenden, aber ich finde es unter bestimmten Bedingungen besser lesbar, als die if-Anweisung am Ende anzuheften. Es ist einfacher, eine if-Anweisung am Ende zu übersehen, und ich möchte nicht immer etwas zurückgeben, wenn die Bedingung nicht erfüllt ist (da Sie mit einem ternären Operator dazu gezwungen werden).

Sie können auch etwas ausführlicher und rubocop-freundlicher sein:

if object.method then a.action end
Allison
quelle