В последнее время мне пришлось прочитать довольно много кода претендентов на позицию Senior Ruby Developer, и теперь, вытащив из глаз затычки, предотвращающие вытекание, я решил поделиться теми типовыми ошибками, которые соискатель делать не имеет права в принципе. Все они напрямую скопированы из разных решений тестового задания. Задание простое, требует немного денежной арифметики, немного простой логики, немного умения спроектировать и организовать малюсенький проектик.  Итак, встречайте: пять самых частых ляпов, зажигающих перед соискателем красный свет.  Оговорюсь, что я никогда не зверствую в кодревью и требую исправить только ошибки. Советую подправить — совсем уж корявый код, и только после апрува. Захочет коллега — исправит перед мерджем, нет — нет. Пример: В последнее время этот тип ошибки уходит в прошлое, вместе с использованием attr_accessor и прочих глобальных прелестей. Тем не менее, иногда хочется определить константу на уровне класса, и, вроде бы, переменная класса для того и была придумана. Чтобы увидеть, в чем тут проблема, надо четко различать классы и инстансы, что немного усложнено тем, что класс — сам по себе тоже инстанс (своего айгенкласса, который синглтон, хм). Так вот, код выше определяет переменную класса на уровне айгенкласса Foo. Всего у нас есть четыре способа объявить переменную с префиксом @: переменные класса или инстанса в разных местах: на уровне класса (в теле определения модуля или класса) на уровне инстанса (внутри метода)  Довольно бойлерплатный кусок кода ниже показывает различия: Если теперь сходить в консоль и глянуть, что там получилось, то результат будет вот таким: Из примечательного тут вот что: определенные на уровне модуля переменные с одной собакой (module instance variables) — из кода методов недоступны, их увидят методы класса, определенные внутри self << class или через def self.get. Но главное, переменная класса оказалась в родителе перетерта из наследника. Это ожидаемое поведение, переменные класса так работают. Поэтому не нужно их использовать примерно никогда. Для этих целей как раз и существует переменная инстанса класса, которая пуста в коде выше; ей просто нужен правильный геттер. Я знаю, что руби — это настоящий ООП, там даже каждое булево значение — инстанс настоящего класса (это не совсем так, на самом деле, но разговор об этом выходит за рамки данной заметки). И тем не менее, не нужно городить классы там, где вам нужны просто структурированные данные. Ходят слухи, что из введения краткой записи рекордов вместо многословного традиционного объявления классов с геттерами и сеттерами — однажды вырос целый язык. В руби вы не сможете защитить ваши данные, если злой коллега захочет их перезаписать, не нужно себя тешить модификаторами private и прочими attr_reader. Поэтому если нужна структура данных — объявите ее как структуру данных. А еще лучше — вообще просто как Hash. Даже, если вам завтра потребуется какая-то аггрегация, — тут все еще руби.   Ладно, шучу, так делать не нужно :) Но и злоупотреблять классами там, где достаточно простого хэша, или структуры — тоже. Это любимая ахиллесова пята всех без исключения рельсовиков (стр. 7), ||: Не делайте так. Определите Hash#default_proc на внутреннем хэше и спокойно отдавайте его наружу (замороженным, если боитесь измен).  Текст уже получается длинноват, поэтому по этому пункту выскажусь кратко: никогда, ни при каких обстоятельствах, не используйте флоаты там, где нельзя вернуть «примерно то же самое, что было передано». Деньги, интервалы в днях, да вообще почти все. Используйте вместо них Rational. Или любую реализацию даблов, если прям принципиальна скорость. И, наконец, венчает наш хит-парад — самый противный код, который вообще только можно представить. Здесь ужасно просто всё. Самое удивительное, что я встречаю подобное насилие над простым проходом по массиву чуть ли не в каждом втором тестовом. объявление переменной вне скоупа вычислений изменение переменной внешнего скоупа изнутри итератора совершенно убийственная многословность ради ничего введение в заблуждение читателя: тут нет итерации как таковой, тут reduce Вот как этот код должен выглядеть: На сегодня, пожалуй, все. А какие ваши любимые ошибки начинающего разработчика в руби?   OSS contributor