2010-02-01 20 views
67

C'è un linguaggio rubino per "Se fai-questo" e "fai-questo" proprio come un semplice comando?Ruby operatore ternario senza altro

per esempio, sto facendo attualmente

object.method ? a.action : nil 

di lasciare la clausola else vuoto, ma mi sento come probabilmente c'è un modo più idiomatico di fare questo che non comporta dover specificare un nullo a fine. (E in alternativa, mi sento come fare il backup di più righe di codice sarebbe uno spreco in questo caso.

+0

Dipende dal contesto, ma a volte è più elegante per leggere un if/while/iniziano blocco con una sola linea nel corpo di qualcosa di più denso/terso. –

risposta

105
a.action if object.method? 
14

risposta di Greg è il migliore, ma per la cronaca, e ancor più che in C, le espressioni e le dichiarazioni sono equivalenti in Ruby, così oltre a.action if o.m? si può anche fare le cose come:

object.method? && a.action 

È possibile scrivere (a; b; c) if d o addirittura

(a 
b 
c 
) if d 

o per quella opaca R: (x; y; z) ? (a; b c) : (d; e; f)

Non c'è situazione in Ruby in cui è consentito solo una singola istruzione o espressione ...

131

Come regola generale: è praticamente mai bisogno l'operatore ternario in Ruby. Il motivo per cui è necessario in C, è perché in C if è un'istruzione, quindi se si desidera restituire un valore, è possibile utilizzare per l'operatore ternario, che è un'espressione.

In Ruby, tutto è espressione, ci sono nessuna dichiarazione, il che rende l'operatore ternario praticamente superfluo. È sempre possibile sostituire

cond ? then_branch : else_branch 

con

if cond then then_branch else else_branch end 

Quindi, nel tuo esempio:

object.method ? a.action : nil 

è equivalente a

if object.method then a.action end 

che, come sottolinea @ Greg Campbell è a sua volta equivalente al trailing if modificatore forma

a.action if object.method 

Inoltre, dal momento che gli operatori booleani in Ruby non solo restituiscono true o false, ma il valore dell'ultima espressione valutata, si possono usare per il flusso di controllo. Questo è un idioma importato da Perl, e sarebbe simile a questa:

object.method and a.action 
+12

Questa è una GRANDE risposta! –

+5

operatore ternario 'cond? a: b' è più breve di 'if cond then a else b end', che da solo mi fa usare per salvare 11 caratteri ;-) – Markus

+0

[Ruby Style Guide] (https://github.com/bbatsov/ruby-style -guide # ternario-operatore) afferma: "Favorisci l'operatore ternario ('?: ') su costrutti' if/then/else/end'.E 'più comune e ovviamente più conciso ". –

2

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

value = 1 result = (value == 1 && 'one') || 'two' result #=> 'one' Spiega: valore == 1 & & 'uno' # => restituisce il risultato dell'ultima espressione, il valore è pari 1 so e la sezione sarà valutata e restituirà 'uno'.

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

Spiega: value = 1 e 'e' non sarà valutata l'espressione, ma instad verrà utilizzato 'o' espressione e restituisce 'due'

0

Un altro modo in cui questo può essere fatto sulla stessa linea è:

if object.method; a.action end 

Questo è considerato un cattivo stile da Rubocop perché utilizza un punto e virgola per terminare l'espressione, ma trovo più leggibile in alcune condizioni di virare su l'istruzione if alla fine. È più facile trascurare un'istruzione if se alla fine e non sempre voglio restituire qualcosa se la condizione non è vera (dato che sei costretto con un operatore ternario).

Si può anche essere un po 'più prolisso e rubocop accogliente:

if object.method then a.action end