Правильное использование модификаторов операторов Ruby - PullRequest
6 голосов
/ 26 декабря 2009

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

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

к этому:

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

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

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

Ответы [ 4 ]

8 голосов
/ 26 декабря 2009

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

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

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

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


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

8 голосов
/ 26 декабря 2009

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

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

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

4 голосов
/ 26 декабря 2009

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

raise ArgumentError, "Invalid direction" unless VALID_DIRECTIONS.include?(direction)
0 голосов
/ 26 декабря 2009

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

...