Come viene utilizzato l'operatore condizionale ( ? :
) in Ruby?
Ad esempio, è corretto?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Come viene utilizzato l'operatore condizionale ( ? :
) in Ruby?
Ad esempio, è corretto?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Risposte:
È l' operatore ternario e funziona come in C (la parentesi non è richiesta). È un'espressione che funziona come:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
Tuttavia, in Ruby, if
anche un'espressione è così: if a then b else c end
=== a ? b : c
, ad eccezione dei problemi di precedenza. Entrambe sono espressioni.
Esempi:
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
Si noti che nel primo caso sono necessarie le parentesi (altrimenti Ruby è confuso perché pensa che sia puts if 1
con un po 'di spazzatura extra dopo di esso), ma non sono richieste nell'ultimo caso poiché il problema non si presenta.
È possibile utilizzare il modulo "long-if" per la leggibilità su più righe:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
e false
. Non molto normale, anzi.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
con parentesi. Altrimenti l'ordine delle operazioni non è chiaro. Quando l'ho letto per la prima volta sono rimasto confuso mentre lo leggevo come (puts true) ? "true" : "false"
allora mi aspettavo puts
di restituire il valore booleano che poi è diventato il valore della stringa.
L'uso di ERB suggerisce che sei su Rails. Se è così, allora considera truncate
, un aiuto integrato che farà il lavoro per te:
<% question = truncate(question, :length=>30) %>
@pst ha dato un'ottima risposta, ma vorrei menzionare che in Ruby l'operatore ternario è scritto su una riga per essere sintatticamente corretto, a differenza di Perl e C dove possiamo scriverlo su più righe:
(true) ? 1 : 0
Normalmente Ruby genererà un errore se si tenta di dividerlo su più righe, ma è possibile utilizzare il \
simbolo di continuazione della riga alla fine di una riga e Ruby sarà felice:
(true) \
? 1 \
: 0
Questo è un semplice esempio, ma può essere molto utile quando si tratta di linee più lunghe poiché mantiene il codice ben strutturato.
È anche possibile usare il ternario senza i caratteri di continuazione della linea mettendo gli operatori per ultimi sulla linea, ma non mi piace o lo consiglio:
(true) ?
1 :
0
Penso che questo porti a un codice davvero difficile da leggere poiché il test condizionale e / oi risultati si allungano.
Ho letto i commenti dicendo di non usare l'operatore ternario perché è confuso, ma questa è una cattiva ragione per non usare qualcosa. Con la stessa logica non dovremmo usare espressioni regolari, operatori di intervallo (' ..
' e la variazione "flip-flop" apparentemente sconosciuta). Sono potenti se usati correttamente, quindi dovremmo imparare a usarli correttamente.
Perché hai messo le parentesi
true
?
Considera l'esempio del PO:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Il wrapping del test condizionale aiuta a renderlo più leggibile perché separa visivamente il test:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Ovviamente, l'intero esempio potrebbe essere reso molto più leggibile usando alcune aggiunte giudiziose di spazi bianchi. Questo non è testato ma avrai l'idea:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
O, più scritto in modo più idiomatico:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Sarebbe facile argomentare che anche la leggibilità soffre molto question.question
.
true
?
true
realtà è seduto per quella che sarebbe un'espressione che valuta true
o false
. È meglio delimitare visivamente quelli poiché le dichiarazioni ternarie possono rapidamente trasformarsi in rumore visivo, riducendo la leggibilità che influisce sulla manutenibilità.
Un semplice esempio in cui l'operatore controlla se l'id del giocatore è 1 e imposta l'id nemico in base al risultato
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
E ho trovato un post sull'argomento che mi sembra abbastanza utile.
enemy_id = player_id == 1 ? 2 : 1
?
Il codice condition ? statement_A : statement_B
è equivalente a
if condition == true
statement_A
else
statement_B
end
Il modo più semplice:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
poiché param_a
non è uguale a param_b
allora il result
valore di saràNot same!
question=question[0,20]
se fosse inferiore a 20, non cambierà nulla.