Friendly attributes pattern in Ruby
Bruno Sutic разработал Friendly Attributes Pattern для упрощения создания тарифных планов в своем проекте RailsBilling. Вместо громоздких повторяющихся вызовов с множеством атрибутов, он предложил компактный синтаксис с хэшами, который моделирует ментальную модель типичной страницы ценообразования. Новый подход преобразует различные структуры (массивы, хэши, значения) в стандартные атрибуты, используя типы данных для интерпретации: символы - как имена планов, числа - как суммы, ActiveSupport::Duration - как интервалы.
Паттерн работает в различных контекстах: в тестах, в консоли Rails, с методами поиска. Он поддерживает передачу аргументов в любом порядке, что удобно для разных языков, и позволяет использовать как отдельные значения, так и сложные структуры. Friendly Attributes является надмножеством стандартных атрибутов, обеспечивая обратную совместимость. Если подход не нравится, можно продолжать использовать традиционные методы без изменений.
Комментарии (65)
This is...not for me. It follows a big pattern in Ruby/Rails culture where to understand the code, you first have to understand the magic. And, it's never all that obvious where to go to try and understand the magic, because the magic itself has been imported by magic.I once was
The bloat of edge-case first libraries
Многие библиотеки в экосистеме JavaScript стали избыточно сложными из-за попыток обработать все возможные крайние случаи, даже те, что на практике почти не встречаются. Например, функция clamp, предназначенная для ограничения чисел, превращается в монстра, проверяющего строки, валидирующего типы и значения, что приводит к появлению микробиблиотек вроде is-number с 90 млн загрузок в неделю. Это результат плохого технического дизайна: вместо чёткого определения ожидаемых входных данных разработчики добавляют слои проверок для гипотетических сценариев.
Правильный подход — проектировать функции под конкретные типы данных, оставляя валидацию значений на усмотрение вызывающей стороны. Библиотеки вроде is-arrayish или pascalcase, принимающие разнородные входы, лишь увеличивают сложность и зависимости без реальной пользы. Стоит вернуться к простоте: в большинстве случаев достаточно встроенных методов языка, а специализированные решения нужны только для узких задач, а не как стандарт.
Комментарии (125)
- Обсуждение критикует избыточное использование зависимостей в JavaScript/TypeScript для простых задач, таких как проверка типов, что ведет к раздуванию экосистемы.
- Участники связывают проблему с историческими особенностями JavaScript: отсутствием строгой типизации и богатой стандартной библиотеки в прошлом.
- Поднимается вопрос о дизайне контрактов функций: следует ли валидировать входные данные внутри функции или возлагать эту ответственность на вызывающую сторону.
- Отмечается культурное различие между сообществами: в Python принята модель "согласованных взрослых", а в JS — оборонительное программирование.
- Обсуждается роль статической типизации (TypeScript) и стандартных библиотек как способа уменьшить потребность в микро-пакетах для проверок.
Object-oriented design patterns in C and kernel development 💬 Длинная дискуссия
Разработка собственной ОС освобождает от ограничений коллективной работы и позволяет экспериментировать с необычными паттернами. Вдохновлённый статьёй LWN «Object-oriented design patterns in the kernel», я реализовал все сервисы ядра через «виртуальные таблицы» (vtables) — структуры с указателями на функции, обеспечивающие полиморфизм на чистом C.
Базовая идея
struct device_ops {
void (*start)(void);
void (*stop)(void);
};
struct device {
const char *name;
const struct device_ops *ops;
};
Разные устройства регистрируют свои реализации ops, а вызывающий код работает с единым интерфейсом. Таблицу можно менять на лету без изменения клиентов.
Применение в моей ОС
- Сервисы: сетевой менеджер, оконный сервер и др. описываются структурой
struct service_ops { void (*start)(void); void (*stop)(void); void (*restart)(void); };
Позволяет из терминала запускать/останавливать потоки без хардкода.
- Планировщик: интерфейс
yield, block, add, nextреализуется разными стратегиями (round-robin, SJF, FIFO). Политику можно заменить без пересборки ядра. - Файлы: как в Unix, «всё есть файл». Сокеты, устройства и обычные файлы предоставляют одинаковые
read/write, скрывая сложность реализации.
Модули ядра
Такой подход легко расширяется динамически загружаемыми модулями-драйверами, как в Linux.
Комментарии (160)
- Обсуждение показывает, что в ядре Linux и других проектах на C давно применяют «объектно-ориентированные» приёмы через структуры с указателями на функции (таблицы виртуальных методов).
- Некоторые считают это удобным и экономным по памяти, другие — источником проблем с читаемостью, отладкой и оптимизацией.
- Упоминаются готовые микро-фреймворки (co2, carbon) и примеры из tmux, где такие паттерны уже используются.
- Спор идёт о необходимости явного параметра this: одни ценят прозрачность, другие — «сахар» неявного this в C++/Java.
- Вопрос «почему бы не перейти на C++/другой язык» сводится к контролю над памятью, отсутствию «магии» и возможности оставаться на C ради производительности и простоты.
Objects should shut up 🔥 Горячее 💬 Длинная дискуссия
—
Комментарии (357)
In safety industries, particularly aviation, "alarm fatigue" is a really big deal. You recognize that pilots have limited situational bandwidth, and you REALLY don't want to be bugging them about things you can avoid. I worked in collision avoidance systems (TAS/TCASI/TCASII), an