Правильное использование модификаторов операторов Ruby

Я только начал работать с Ruby и обнаружил модификаторы операторов, когда RubyMine предложил мне изменить этот код:

if !VALID_DIRECTIONS.include?(direction)
   raise ArgumentError, "Invalid direction"
end

для этого:

raise ArgumentError, "Invalid direction" if !VALID_DIRECTIONS.include?(direction)

мне нравится, как это делает код более лаконичным. Однако я могу видеть, что это потенциально вводит в заблуждение на первый взгляд и навязывает проблему читаемости, потому что она ставит эффект перед условием. Опять же, может это просто потому что я так привык к c-подобным языкам.

кто-нибудь столкнулся проблема в результате использования модификаторов операторов или вы считаете, что они улучшили ваш код? Кроме того, у кого-нибудь есть общие рекомендации по использованию модификаторов (т. е. работает особенно хорошо для некоторых операций или нет для некоторых других)?

4 ответов


Я нахожу, что у меня обычно нет проблем с чтением этих трейлинг-условий (как их иногда называют), при условии, что другое руководящие принципы читабельности кода продолжается. Помещая 60-символьное выражение и 40-символьное условие в одну строку, вы получите 100-символьный сгусток текста, который, безусловно, будет нечитаемым, полностью независимым от вопроса о конечных условных обозначениях.

в конкретном примере кода Вы показываем, это довольно очевидно, что там должны быть условным следующим. Кто бы захотел!--0--> an ArgumentError даже не взглянув сначала на аргументы?

кроме того, конечные условные обозначения похожи на предложения guard в математических и функциональных языках, которые также имеют тенденцию быть написанными после выражение, которое они охраняют.

последнее, но не менее важное, поставив пару raise Bar if foo и return nil if quux выражения в начале методы, как вид охранников, на самом деле считаются хороший style, чтобы упростить поток управления методом. Опять же: поскольку они приходят в начале метода, очевидно, что там и состояние, в противном случае returning с самого начала метода не имело бы смысла.


PS: Я бы на самом деле использовать unless есть, чтобы избавиться от отрицания. С более сложными условиями, я нахожу, что unless иногда можно трудно разобрать, но в данном случае, это больше очевидно, по крайней мере ИМХО.


модификаторы операторов делают ruby более похожим на английский, что приятно:

  • если идет дождь, оставайтесь дома
  • остаться дома, если идет дождь

Я бы посоветовал вам использовать форму, которая кажется вам самой естественной и элегантной. Если сомневаетесь, прочитайте заявление вслух в обеих формах. Лично я склонен использовать только модификаторы операторов для коротких операторов, таких как return :nope if input.nil? -- для более длинних или более осложненных заявлений, оно может принять читателя более длиной к схватите, потому что глаза только покрывают некоторое количество космоса и поэтому кто-то только прочитал бы модификатор на втором взгляде.


сначала это было немного странно для меня, но я не думаю, что это создает проблему читаемости. При работе в Ruby много, это имеет смысл. Это заметно только тогда, когда я переключаюсь туда и обратно с другими языками. Однако, когда вы погрузитесь в код Ruby, вы найдете его чистым и кратким способом написания одной строки conditionals. Кроме того, привыкайте использовать unless. Ваш код может (может) быть написано:

raise ArgumentError, "Invalid direction" unless VALID_DIRECTIONS.include?(direction)

Это чисто субъективный вопрос стиля. Используйте все, что вам удобно.