Як умовний оператор ( ? :) використовується в 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
Зверніть увагу, що в першому випадку потрібні круглі дужки (інакше Рубі плутається через те, що думає, що це 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значення «s будеNot same!
question=question[0,20]Якщо він був меншим за 20, це не змінить.