Есть ли какие-либо особенности языка Ruby, которых вы избегаете? - PullRequest
8 голосов
/ 04 июня 2009

Мне кажется, что в Ruby много синтаксической гибкости, и многие вещи могут быть написаны несколькими способами.

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

Если ваш ответ: «Я использую все!», Вы когда-нибудь комментировали код, который был бы очевиден, если бы читатель знал соответствующий синтаксис Ruby?

[Меня особенно интересует Ruby в контексте RoR, но все приветствуется.]

Ответы [ 8 ]

11 голосов
/ 04 июня 2009

Весь диапазон глобальных переменных "$" (см. Pickaxe2 pp333-336), в основном унаследованных от Perl, довольно ужасен, хотя я иногда обнаруживал, что использую $: вместо $ LOAD_PATH.

8 голосов
/ 04 июня 2009

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

7 голосов
/ 04 июня 2009

Цикл for ... in ... Он напрямую компилируется в obj.each (и соответственно выдает странное сообщение об ошибке) и совершенно не нужен. Я даже не вижу, где это улучшает читабельность - если вы были в рубине более недели, #each должен быть естественным.

6 голосов
/ 05 июня 2009

Прежде всего: я нарушу многие из этих правил, если это будет для короткого одноразового скрипта, или для одной строки в командной строке, или в irb. Но большую часть моего времени я провожу в скриптах или приложениях среднего или большего размера. Итак:

Избегайте:

  • с использованием class << self блока кода для методов класса. Это милый трюк, но не лучше, чем def self.foo, и менее читаемый (особенно после первой страницы).
  • for i in collection: используйте взамен collection.each.
  • proc {...}: обычно lambda {...} лучше.
  • переменные класса (например, @@foo). Они проблематичны и обычно могут быть заменены переменными экземпляра уровня класса без особых усилий.
  • Все, что вызывает предупреждение, и предпочтительно все, что вызывает предупреждение при запуске через более строгий ruby -w. Это особенно важно, если вы пишете драгоценный камень для использования другими.
  • 'else' в блоке 'begin ... rescue ... end'. Личные предпочтения: это слишком сложный случай, и поэтому мало кто даже знает, что он существует или как он работает, чтобы того стоить.
  • ObjectSpace и GC. Вам, вероятно, не нужно идти туда. Вы определенно не хотите туда идти.
  • =begin и =end многострочные комментарии. Личное предпочтение построчным комментариям. Это просто чертовски раздражает меня.

Используйте это, но экономно или как последнее средство (и прокомментируйте это соответственно):

  • eval (или class_eval и т. Д.) При передаче строки. Есть несколько приемов метапрограммирования, которые вы просто не можете сделать, не передавая строку. И иногда, строковая версия работает значительно лучше (а иногда это имеет значение). В противном случае я предпочитаю посылать блоки реального кода ruby ​​для моего метапрограммирования. eval можно полностью избежать для многих задач метапрограммирования.
  • Добавление или переопределение методов для классов, которые не были созданы мной и могут использоваться кодом вне моего контроля; А.К.А. Обезьяны-исправления. Это правило в основном для больших кодовых баз и библиотек; Я с удовольствием и быстро сделаю исключение для небольших одноразовых сценариев. Я также сделаю исключение для исправления ошибок в сторонних библиотеках (хотя вы можете застрелиться в ногу при обновлении!). Пространства имен селекторов (или что-то подобное) будут иметь большое значение, чтобы сделать рубин приятным в этом отношении. Тем не менее, иногда это стоит того. ; -)
  • Глобальные переменные (кроме классов). Я даже передам $ stdout в качестве параметра моим объектам или методам, а не буду использовать их напрямую. Это делает повторное использование кода намного проще и безопаснее. Иногда вы не можете избежать этого (например, $0, $:, $$ и другие переменные среды, но даже тогда вы можете ограничить свое использование).
    • Говоря об этом, я предпочитаю ограничить использование глобальных символов perlish полностью, но если их нужно использовать чуть больше, тогда require "English".
  • break, redo, next, try: Часто они делают блок, цикл или метод гораздо более элегантным, чем могло бы быть. Обычно они просто заставляют вас почесать голову на несколько минут, когда вы давно не видели этот код.
  • __END__ для блока данных. Отлично подходит для небольшого однофайлового скрипта. Бесполезно для многофайлового приложения.

Не используйте его, но не избегайте этого:

  • попытаться / поймать
  • продолжений

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

  • 'and' и 'or': они имеют приоритет выше, чем && и ||, поэтому с ними нужно быть осторожнее. Я считаю их различные приоритеты очень полезными.
  • регулярное выражение черной магии (при условии, что у меня есть несколько примеров в модульных тестах для него)
  • HEREDOC строк
6 голосов
/ 04 июня 2009

Это может быть очевидно, но я обычно избегаю использования eval, если есть какая-либо альтернатива.

1 голос
/ 06 июня 2009

Избегайте объединения слишком большого количества вызовов методов вместе. В Ruby очень распространено объединение методов.

user.friends.each {|friend| friend.invite_to_party}

Это может показаться нормальным, но нарушает Закон Деметры :

Более формально, закон Деметры для функций требует, чтобы метод M объекта O мог вызывать только методы следующих типов объектов:

  1. О себе
  2. Параметры М
  3. любые объекты, созданные / созданные в пределах М
  4. Объекты прямого компонента O

Пример выше не идеален, и лучшим решением будет что-то вроде этого:

user.invite_friends_to_party

Проблема в примере не является ошибкой Руби, но очень легко создать код, который нарушает Закон Деметры и делает код нечитаемым.

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

1 голос
/ 05 июня 2009

Одна вещь, которую я действительно ненавижу, это «неправильное» использование {} и do ... end для блоков. Кажется, я не могу точно найти, где я изучил практику, но обычно принято делать {} для однострочных блоков и do ... end для многострочных.

Правильное использование:

[1, 2, 3, 4].map {|n| n * n }.inject(1) { |n,product| n * product }

или

[1, 2, 3, 4].inject do |n,product|
  n = n * n
  product = n * product
end

Неправильное использование:

[1,2,3,4].map do |n| n * n end.inject(1) do |n,product| n * product end

или

[1, 2, 3, 4].inject { |n,product|
  n = n * n
  product = n * product
}

Все из которых, конечно, выполнят подачу 576

0 голосов
/ 11 июня 2009
begin nil+234 rescue '' end

приведенный выше синтаксис действителен, но вы никогда не должны его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...