Как условный оператор ( ? :) используется в 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, это ничего не изменит.