Как условный оператор ( ? :
) используется в Ruby?
Например, это правильно?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Как условный оператор ( ? :
) используется в Ruby?
Например, это правильно?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Ответы:
Это троичный оператор , и он работает как в C (круглые скобки не требуются). Это выражение работает так:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
Однако в Ruby if
также есть выражение: if a then b else c end
=== a ? b : c
, за исключением проблем с приоритетами. Оба выражения.
Примеры:
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
Обратите внимание, что в первом случае требуются круглые скобки (в противном случае Ruby путается, потому что думает, что это puts if 1
с каким-то дополнительным мусором после него), но они не требуются в последнем случае, так как упомянутая проблема не возникает.
Вы можете использовать форму long-if для удобства чтения на нескольких строках:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
и false
. Не очень обычно, действительно.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
с круглыми скобками. В противном случае порядок операций неясен. Когда я впервые прочитал это, я был сбит с толку, поскольку я читал это, как (puts true) ? "true" : "false"
тогда ожидалось, puts
чтобы вернуть логическое значение, которое затем стало строковым значением.
Ваше использование ERB предполагает, что вы находитесь в Rails. Если это так, то подумайте truncate
, встроенный помощник, который сделает эту работу за вас:
<% question = truncate(question, :length=>30) %>
@pst дал отличный ответ, но я хотел бы отметить, что в Ruby троичный оператор записан в одну строку, чтобы быть синтаксически правильным, в отличие от Perl и C, где мы можем написать его в несколько строк:
(true) ? 1 : 0
Обычно Ruby вызывает ошибку, если вы пытаетесь разбить ее на несколько строк, но вы можете использовать \
символ продолжения строки в конце строки, и Ruby будет счастлив:
(true) \
? 1 \
: 0
Это простой пример, но он может быть очень полезен при работе с более длинными строками, так как он хорошо выкладывает код.
Также возможно использовать троичный без символов продолжения строки, помещая операторы последними в строке, но я не люблю или не рекомендую это:
(true) ?
1 :
0
Я думаю, что это приводит к тому, что код становится действительно трудно читать, поскольку условный тест и / или результаты становятся длиннее.
Я читал комментарии о том, что нельзя использовать троичный оператор, потому что это сбивает с толку, но это плохая причина не использовать что-то. По той же логике мы не должны использовать регулярные выражения, операторы диапазона (' ..
' и, казалось бы, неизвестный вариант "триггера"). Они эффективны при правильном использовании, поэтому мы должны научиться правильно их использовать.
Почему вы поставили скобки вокруг
true
?
Рассмотрим пример ОП:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Упаковка условного теста помогает сделать его более читабельным, поскольку он визуально разделяет тест:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Конечно, весь пример можно сделать намного более читабельным, если использовать некоторые разумные добавления пробелов. Это не проверено, но вы получите идею:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
Или, более написано более идиоматически:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Было бы легко утверждать, что читаемость question.question
тоже сильно страдает .
true
?
true
что на самом деле сидит за то, что будет выражением, которое оценивает true
или false
. Лучше визуально разграничить их, поскольку троичные операторы могут быстро перерасти в визуальный шум, снижая читабельность, что влияет на удобство обслуживания.
Простой пример, где оператор проверяет, равен ли идентификатор игрока 1, и устанавливает идентификатор врага в зависимости от результата.
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
И я нашел пост на тему, который кажется довольно полезным.
enemy_id = player_id == 1 ? 2 : 1
?
Код condition ? statement_A : statement_B
эквивалентен
if condition == true
statement_A
else
statement_B
end
Самый простой способ:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
так param_a
как не равно, param_b
то result
значение будетNot same!
question=question[0,20]
если он был меньше 20, это ничего не изменит.