Como é o operador condicional (? :
) é usado no Ruby?
Por exemplo, isso está correto?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Como é o operador condicional (? :
) é usado no Ruby?
Por exemplo, isso está correto?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Respostas:
É o operador ternário e funciona como em C (os parênteses não são necessários). É uma expressão que funciona como:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
No entanto, em Ruby, if
também é uma expressão assim: if a then b else c end
===a ? b : c
, exceto para problemas de precedência. Ambos são expressões.
Exemplos:
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
Observe que, no primeiro caso, são necessários parênteses (caso contrário, Ruby fica confuso porque acha que está puts if 1
com algum lixo extra depois dele), mas eles não são necessários no último caso, pois o problema não ocorre.
Você pode usar o formulário "long-if" para facilitar a leitura em várias linhas:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
e false
. Não é muito usual, de fato.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
entre parênteses. Caso contrário, a ordem das operações não é clara. Quando li pela primeira vez, fiquei confuso ao ler o que era (puts true) ? "true" : "false"
esperado puts
para retornar o booleano que se tornou o valor da string.
Seu uso do ERB sugere que você esteja no Rails. Em caso afirmativo, considere truncate
um auxiliar embutido que fará o trabalho para você:
<% question = truncate(question, :length=>30) %>
O @pst deu uma ótima resposta, mas eu gostaria de mencionar que em Ruby o operador ternário está escrito em uma linha para estar sintaticamente correto, ao contrário do Perl e C, onde podemos escrevê-lo em várias linhas:
(true) ? 1 : 0
Normalmente, Ruby gera um erro se você tentar dividi-lo em várias linhas, mas você pode usar o \
símbolo de continuação de linha no final de uma linha e Ruby ficará feliz:
(true) \
? 1 \
: 0
Este é um exemplo simples, mas pode ser muito útil para lidar com linhas mais longas, pois mantém o código bem organizado.
Também é possível usar o ternário sem os caracteres de continuação de linha colocando os operadores por último na linha, mas eu não gosto ou recomendo:
(true) ?
1 :
0
Eu acho que isso leva a um código realmente difícil de ler à medida que o teste e / ou resultados condicionais ficam mais longos.
Eu li comentários dizendo para não usar o operador ternário porque é confuso, mas esse é um mau motivo para não usar algo. Pela mesma lógica, não devemos usar expressões regulares, operadores de intervalo (' ..
' e a variação "flip-flop" aparentemente desconhecida). Eles são poderosos quando usados corretamente, por isso devemos aprender a usá-los corretamente.
Por que você colocou colchetes
true
?
Considere o exemplo do OP:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
O agrupamento do teste condicional ajuda a torná-lo mais legível porque separa visualmente o teste:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Obviamente, todo o exemplo poderia ser muito mais legível usando algumas adições criteriosas de espaço em branco. Isso não foi testado, mas você terá a ideia:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
Ou, mais escrito mais idiomaticamente:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Seria fácil argumentar que a legibilidade também sofre question.question
muito.
true
?
true
está na verdade substituindo o que seria uma expressão avaliada como true
ou false
. É melhor delimitar visualmente as declarações, pois as declarações ternárias podem se transformar rapidamente em ruído visual, reduzindo a legibilidade que afeta a capacidade de manutenção.
Um exemplo simples em que o operador verifica se o ID do jogador é 1 e define o ID do inimigo, dependendo do resultado
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
E eu encontrei um post sobre o tópico que parece bastante útil.
enemy_id = player_id == 1 ? 2 : 1
?
O código condition ? statement_A : statement_B
é equivalente a
if condition == true
statement_A
else
statement_B
end
Caminho mais fácil:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
desde que param_a
não seja igual a, param_b
então o result
valor seráNot same!
question=question[0,20]
Se fosse menor que 20, não mudaria nada.