Jak ? :
używany jest operator warunkowy ( ) w Ruby?
Na przykład, czy to jest poprawne?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Jak ? :
używany jest operator warunkowy ( ) w Ruby?
Na przykład, czy to jest poprawne?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Odpowiedzi:
Jest to operator trójskładnikowy i działa jak w C (nawiasy nie są wymagane). To wyrażenie działa jak:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
Jednak w Ruby if
jest także wyrażenie: if a then b else c end
===a ? b : c
, z wyjątkiem kwestii pierwszeństwa. Oba są wyrażeniami.
Przykłady:
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
Zauważ, że w pierwszym przypadku wymagane są nawiasy (w przeciwnym razie Ruby jest zdezorientowana, ponieważ uważa, że jest puts if 1
z dodatkowymi śmieciami), ale w ostatnim przypadku nie są one wymagane, ponieważ wspomniany problem nie pojawia się.
Możesz użyć formularza „long-if” dla czytelności w wielu wierszach:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
i false
. Rzeczywiście niezbyt często.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
z nawiasami. W przeciwnym razie kolejność operacji nie jest jasna. Kiedy po raz pierwszy to przeczytałem, byłem zdezorientowany, ponieważ czytałem to, ponieważ (puts true) ? "true" : "false"
spodziewałem puts
się zwrócić wartość logiczną, która następnie stała się wartością ciągu.
Twoje użycie ERB sugeruje, że jesteś w Railsach. Jeśli tak, to weź pod uwagę truncate
wbudowanego pomocnika, który wykona za Ciebie zadanie:
<% question = truncate(question, :length=>30) %>
@pst dał świetną odpowiedź, ale chciałbym wspomnieć, że w Ruby operator trójskładnikowy jest napisany w jednym wierszu, aby był poprawny pod względem składniowym, w przeciwieństwie do Perla i C, gdzie możemy napisać go w wielu wierszach:
(true) ? 1 : 0
Normalnie Ruby zgłosi błąd, jeśli spróbujesz podzielić go na wiele linii, ale możesz użyć \
symbolu kontynuacji linii na końcu linii, a Ruby będzie szczęśliwa:
(true) \
? 1 \
: 0
Jest to prosty przykład, ale może być bardzo przydatny w przypadku dłuższych linii, ponieważ utrzymuje ładnie ułożony kod.
Możliwe jest również użycie trójki bez znaków kontynuacji linii poprzez umieszczenie operatorów na końcu linii, ale mi się to nie podoba lub nie polecam:
(true) ?
1 :
0
Myślę, że prowadzi to do naprawdę trudnego do odczytania kodu, ponieważ test warunkowy i / lub wyniki stają się dłuższe.
Czytałem komentarze mówiące, aby nie używać operatora trójskładnikowego, ponieważ jest to mylące, ale to zły powód, aby czegoś nie używać. Zgodnie z tą samą logiką nie powinniśmy używać wyrażeń regularnych, operatorów zakresów („ ..
” i pozornie nieznanej odmiany „flip-flop”). Są potężne, gdy są właściwie używane, dlatego powinniśmy nauczyć się ich poprawnie używać.
Dlaczego wstawiłeś nawiasy
true
?
Rozważ przykład PO:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Zawijanie testu warunkowego pomaga uczynić go bardziej czytelnym, ponieważ wizualnie oddziela test:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Oczywiście cały przykład można uczynić o wiele bardziej czytelnym, stosując rozsądne dodatki do białych znaków. To nie zostało przetestowane, ale wpadniesz na pomysł:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
Lub, bardziej napisane bardziej idiomatycznie:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Łatwo byłoby argumentować, że czytelność również bardzo ucierpiała question.question
.
true
?
true
tak naprawdę zasiada za czymś, co byłoby wyrażeniem, które ocenia na true
lub false
. Lepiej oddzielić je wizualnie, ponieważ potrójne stwierdzenia mogą szybko przekształcić się w szum wizualny, zmniejszając czytelność, co wpływa na łatwość konserwacji.
Prosty przykład, w którym operator sprawdza, czy identyfikator gracza wynosi 1, i ustawia identyfikator wroga w zależności od wyniku
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
I znalazłem post na ten temat, który wydaje się bardzo pomocny.
enemy_id = player_id == 1 ? 2 : 1
?
Kod condition ? statement_A : statement_B
jest równoważny z
if condition == true
statement_A
else
statement_B
end
Najprostszy sposób:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
ponieważ param_a
nie jest równa, param_b
wówczas result
wartość będzieNot same!
question=question[0,20]
Jeśli byłby mniejszy niż 20, nie zmieni tego.