Size: a a a

2017 August 24
2pegramming
Недавно нашел статью (https://m.habrahabr.ru/post/158011/, оригинал: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) про паттерны для моделей в Rails от 2012 года.  Подскажи, насколько эти паттерны актуальны и часто ли их приходится применять на практике. Заранее спасибо!https://m.habrahabr.ru/post/158011/, оригинал: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) про паттерны для моделей в Rails от 2012 года.  Подскажи, насколько эти паттерны актуальны и часто ли их приходится применять на практике. Заранее спасибо!

Я считаю, что эти паттерны актуальны даже сейчас. Если присмотреться, они об одном и том же: разделяй логику на изолированные объекты и радуйся жизни. Конечно, можно не следовать паттернам, но необходимо задавать самому себе вопрос: «А действительно ли код, который я написал, должен быть в этом месте, или нет?».

Получается, рельсовые параметры нам всё равно нужно постоянно пермитить? (вопрос по последнему примеру)

Мне не приходилось таким заниматься, но думаю, ответ легко найти в интернете. Например, на SO описывается один из вариантов, как отключить параметры:
https://stackoverflow.com/questions/18092475/in-rails-4-disable-strong-parameters-by-default

Думал, что `Dry::Validation.Schema` на выходе будет выкидывать все параметры, которые не описаны в схеме, это возможно? Просто получается, что если в запросе будет куча лишнего хлама, и описанные параметры проходят валидацию, то лишние параметры тоже остаются, и приходится их самому подчищать, иначе при попытке сохранить запись будет эксепшен, что переданы дополнительные параметры, о которых модель не в курсе, и запись не сохранится.

Я допустил ошибку в примере. Используйте form-валидацию. Эта валидация обрезает неуказанные параметры, что решает проблему.


schema = Dry::Validation.Form do
 required(:email).filled(:str?)
 required(:age).maybe(:int?, gt?: 18)
end

schema.call('email' => 'jane@doe.org', 'age' => '')
# => #<Dry::Validation::Result output={:email=>"jane@doe.org", :age=>nil} errors={}>

schema.call('email' => 'jane@doe.org', 'age' => '', 'firstname' => 'anton')
# => #<Dry::Validation::Result output={:email=>"jane@doe.org", :age=>nil} errors={}>
источник
2017 August 25
2pegramming
#закладки №1

Статьи

* www.blackbytes.info/2017/08/how-does-sinatra-work
Статья о том, как работает Sinatra и что происходит, когда в коде появляется require 'sinatra'. Если хотите прокачаться, в процессе чтения попробуйте написать свою собственную реализацию этого фреймворка с таким же синтаксисом.

* jakeyesbeck.com/2016/03/13/the-power-of-arel
Arel — библиотека, которая вызывает либо отвращение, либо отвращение. Я не знаю ни одного человека, которому бы нравился код, написанный на ней. Так как Arel — low level библиотека для работы Active Record, в коде иногда приходится использовать этот гем. Обычно найти нормальную документацию на эту библиотеку сложно, но статья по ссылке хороша тем, что содержит примеры селектов, джойнов и сложных выборок.

* nicksda.apotomo.de/2011/07/are-class-methods-evil/
* andrzejonsoftware.blogspot.ru/2011/07/yes-nick-class-methods-are-evil.html
Я не фанат методов класса. В коде стараюсь использовать такие методы только по необходимости, либо для создания фабрик и других инициализаторов. В этих двух статьях на примерах рассказано о том, почему не стоит использовать методы классов. Советую также почитать комментарии — там много интересной информации.

* robots.thoughtbot.com/rebuilding-git-in-ruby
Лонгрид о том, как написать git на чистом Ruby. Постарайтесь не просто прочитать статью, но и написать код самостоятельно, без копипаста. Потом запустите программу и проверьте, что всё работает корректно.

* stillflowing.net/2014/12/21/an-experience-in-contributing-to-open-source
Автор рассказывает, почему не надо заниматься опенсорсом ради опенсорса. Ключевая идея: лучше просто пишите код, и во время этого процесса вы найдете проблему, которую можно решить с помощью Open Source.


Репозитории

* reqres-api/reqres_rspec
Интересное решение для того, чтобы генерировать документацию из тестов. Я не использовал эту библиотеку, но планирую испытать ее в деле с Hanami и dry-web приложениями. К сожалению, у библиотеки нет тестов и непонятно, будет ли гем работать с нерельсовыми проектами. Поэтому, если у вас есть время и желание помочь, велкам.

* donnemartin/system-design-primer
Материал о том, как работают разные части веб-приложений. Это популярный текст, который не раз попадал в рассылки или подкасты. У репозитория с этим текстом — 16 тысяч звезд, хотя в нём лежит довольно разрозненная информация. Есть ссылка на русский перевод, который можно дополнить, если есть желание. Вот вам готовая идея для PR: просто дополните гайд и помогите другим разработчикам.

* muan/dashboard
Расширение для Chrome, которое фильтрует информацию на главной странице Github. Скажу честно, мне не нравится Github feed и я раздумывал написать приложение, которое исправило бы эту ситуацию. Но плагин решает проблему: отфильтрованный фид выглядит намного информативнее.


Опенсорс

* slim-template/language-slim/issues/25
Автор Slim ищет помощников. Хотите помочь 10 миллионам человек (на самом деле это количество скачиваний гема)? Есть свободные пара часов в неделю? Напишите автору и предложите помощь. А если сомневаетесь — я уже писал, почему Open Source — это круто (https://t.me/pepegramming/43).

* hanami/events/issues
Если знаете, почему важен event sourcing, хотите прокачаться в асинхронщине и работе с Kafka, Postgres, Redis и другими крутыми штуками — велкам. По ссылке — много открытых ишью, которые ждут своих героев.
источник
2017 August 28
2pegramming
Благодаря трекингу времени, проведенного за компьютером, обнаружил, что в последний месяц, трачу половину дня на соцсети и месенджеры. Из-за этого я захотел провести экспиремент и не пользоваться меcсенджерами (кроме рабочего слака) и социальными сетями на 7 дней.

Поэтому, к сожалению, в канале будет перерыв на эту неделю. А пока можно вспомнить старые сообщения или задать вопросы. А также прочитать пост Андрея Ситника о цифровом шаббате.
источник
2017 September 11
2pegramming
Ребята из RailsClub из года в год делают самую крупную Ruby-конференцию в России с иностранными спикерами. В этом году ожидаются выступления авторов dry, rom, Hanami и Trailblaizer, а также крутых разработчиков со всей страны.

Мне предложили разыграть один бесплатный билет на конференцию. Чтобы розыгрыш был справедливым, надо будет выполнить небольшое задание.

Задача
Важно, чтобы участие в конкурсе принесло пользу не только победителям, но и всем остальным. Поэтому формат будет таким:
- В комментариях под ишью опишите технические проблемы, с которыми вам приходится сталкиваться в своей работе.
- Один комментарий — одна проблема, о которой хочется рассказать другим.
- Ставьте 👍 понравившемуся комментарию и выбирайте победителя.

А если вы захотите сделать мир чуть лучше — у вас появится целый список задач, над которыми можно поработать в будущем.

Награда
Человек с наибольшим количеством 👍 получит бесплатный входной билет на конференцию RailsClub 2017, которая состоится 23 сентября в Москве.
Обладателям второго и третьего мест я привезу сувениры из Японии.

Условия
Конкурс завершается 18 сентября. Каждый участник может отправить неограниченное количество историй. Флуд и спам будут удаляться.

Полезное
- Напишите вашу историю как можно быстрее — так у вас будет больше шансов собрать максимальное количество голосов
- Почитайте пост о том, почему конференции — это круто и что вы можете получить от них помимо докладов
- И еще один старый пост — про то, что делать до, во время и после конференциии
источник
2017 September 19
2pegramming
Конкурс завершен!
В течение недели вы писали свои истории о проблемах, с которыми приходится сталкиваться в работе https://github.com/moscowrb/organisation/issues/3. Спасибо всем, кто поделился наболевшим и рассказал о своей проблеме.
Наибольшее количество лайков собрал рассказ Nikolay Shebanov (https://github.com/killthekitten). Николай получает бесплатный билет на RailsClub 2017. Поздравляем!
На 2 и 3 месте соответственно оказались Кирилл (https://github.com/mephody-bro) и domenic99 (https://github.com/domenic99). Пожалуйста, напишите мне в личку @davydovanton, чтобы забрать свой сувенир из Японии.
источник
2018 March 12
2pegramming
#quality

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

Как выглядело мое ревью раньше: смотрел построчно каждые изменения в ПР, проверял, что тесты проходят и код выглядит ок. Классы на местах, логика последовательна. После - апрувил и был доволен. Вместо этого, попробуйте придерживаться иной последовательности, когда в следующий раз будете ревьювить ПР коллеги.

Понимание задачи

Начните с главного, понимания задачи, которую пытается решить разработчик. Важно: поймите бизнес требование, а не текущую реализацию. Проверьте, разбиваются изменения на 2 и больше пулл реквеста или нет. Если сложно - попросите коллегу о помощи или подробном описании того, зачем изменения нужны. На этом этапе определяется насколько сложную и значимую задачу решал разработчик, а ревьюверы погружается в контекст проблемы. Правило, которого стараюсь придерживаться: 1 пулл реквест == 1 атомарная задача, которую просто понять и просто объяснить на каждом из уровней абстракции.

Проверка, что задача выполнена

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

Проверка архитектуры и способа решения

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

Проверка кода и грамматики

Последний шаг - скрупулезная проверка кода. Тут проверяется нейминг, стилистические особенности, проверяется перформанс.

Подитожив, можно увидеть такую последовательность:


Понимание задачи -> проверка, что задача выполнена -> проверка архитектуры и способа решения -> проверка кода и грамматики
источник
2pegramming
Персональные выводы

Такой способ проверки кода трудозатратен, что значит дороже для бизнеса. Разработчик тратит больше времени на ревью, но при этом команда улучшает качество кода, увеличивается вовлеченность команды, из этого следует, что знания шарятся лучше (а это увеличение bus фактора).

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

В идеале, каждый ревьювер обязан проверить лично, что фича работает корректно. Но настройка окружения и подготовка данных - медленный процесс. Поэтому выгоднее потратить время одного разработчика и сделать скриншоты или видео того, как работает новый код, чем тратить время N ревьюверов на одну и ту же работу.

Сложность ревью пропорциональна количеству кода. Чтобы справляться с этим, разбивайте работу на "атомарные" пулл реквесты, которые не превышают N строк (например - 200 для кода без тестов). Например, в опен сорс проектах, я стал просить людей разбивать работу над задачей на отдельные пулл реквесты

Для последнего шага ревью необходима внимательность, но с этим возникают проблемы у отдельных людей (ADHD напрмиер). При этом, базовые проверки, таких как стиль, грамматика и опечатки автоматизируются с помощью код стайла с rubocop, danger и codeclimate, который показывает, какие части пулл реквеста не покрыты тестами.

Как говорилось, главный минус такого подхода в повышенной энергозатратности для ревьюверов. Отсутствие настроения или желания, авралы и слабость - нормальные явления. Поэтому не стоит огорчаться, если не получается с первого, второго и даже десятого раза. Главное - регулярность и поддержка команды.

Не стоит писать комментарии на каждый из шагов разом. В идеале, если ревью не прошло шаг, стоит остановиться и подождать когда код "пойдет дальше". Не стоит захламлять ПР, разработчик может не понять где проблемы, а где просто мысли или вторичные проблемы, которые опускаются.

# Запомнить

- понимание задачи > выполнение задачи > архитектура > текст
- работающий код > идеальный код
- поймите контекст и важность задачи, перед тем как смотреть код
- цените время разработчика, не просите исправлять то, что изменится
- меньше кода - меньше конгнетивная нагрузка для ревьюверов и быстрее процесс ревью
- автоматизируйте, если это возможно

# Полезное

- 11 советов, как улучшить ревью от IBM
- Еще советы, на этот раз от asana
- И еще советы
- Посмотрите, как Лука пишет описания к ПР-ам в ханами, у него есть чему научиться
источник
2pegramming
источник
2pegramming
А каких правил вы придерживаетесь в ревью и на что смотрите в первую очередь? (обратная связь тут - @davydovanton)
источник
2018 March 18
2pegramming
@shiroginne поделился подробной воскресной статьей о вещах, которые стоит помнить во время ревью:
https://medium.com/@palantir/code-review-best-practices-19e02780015f

А @alexsubbotin поделился CONTRIBUTING.md файлом, дополненым после текста выше:
https://gist.github.com/KELiON/45cae7ac0eeeaa2a097116396c94b610
источник
2018 March 19
2pegramming
В программировании много абстракций, которые кажутся сложными на первый взгляд, но после практики становятся понятнее. Например - монады.

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

Не значит, что монады - серебряная пуля, которая решит любую проблему. Так же, это не значит, что использование монад - единственно верный способ написания кода.

Поэтому, цель текста - не объяснить что такое монада, а показать, как и где начать ее использовать . Не ждите функторов, аппликативных функторов, математических выкладок и подробного объяснения зачем каждая монада нужна. Только практика и императивное объяснение. Статьи для любопытных:

* Объяснение функторов и монад в картинках
* Объяснение в HaskellWiki
* A Fistful of Monads - Learn You a Haskell for Great Good!


Код

Встречаются места когда приходится работать с данными и состояниями, например валидны данные или нет, вернула бд данные и если да - какие это данные, etc. Например:

response = http.get(url, params)
if response[:status] == :success
 user_repository.create(response[:body])
end


Пример не выглядит сложным, но с бизнес логикой - вложенность выходит из под контроля:

response = http.get(url, params)
if response[:status] == :success
 validation_result = validator.call(response[:body])

 if validation_result.valid?
   if user = user_repository.create(response[:body])
     NotificationWorker.perform_async(user.id)
   end
 else
   validation_result.errors
 end
else
 response
end


Вариант с гардами мне показался сложнее для восприятия

Вспоминая railway programming, было бы здорово переписать наш пример с использованием последовательных шагов:

step :get_response # returns response or Failed result
step :validate # returns payload or error message
step :persist # returns user or nothing
step :notify # calls worker with user id


В случаях, когда данные из прошлого шага влияют на последовательность логики, приходят на помощь монады. Важно запомнить, что монада - объект с общим интерфейсом, в котором лежит значение. Ближайшая абстракция - коробка. В коробке лежит все, что поместиться. При этом, не открыв коробку - значение не получить. Коробки - разные, большие, маленькие, цветные, но каждая коробка открывается одинаково - просто подними крышку и посмотри что там.
источник
2pegramming
Монада - инструмент, который позволяет создавать цепочки вызовов функций или методов без лишних проверок данных, которые возвращаются в предыдущем шаге. Монад много, но рассмотрим только популярные - Maybe, Result и Try.

* Maybe - оборачивает значение в Some или возвращает None объект без значения.

* Result - оборачивает значение в Success или Failure.

* Try - оборачивает вызов кода в Result если не было эксепшенов и в Error, если код упал с ошибкой (которая ловится)

У каждой из монад есть 3 главных функции, fmap, bind и способ получить данные, которые содержит в себе монада.

* fmap - выполняет блок, если значение монады соответствует Success варианту, а результат выполнения блока оборачивает в ту же монаду, у которой он вызвался. Например:

Some(1).fmap(&:to_s) # => Some('1')
None().fmap(&:to_s) # => Nothing


* bind - аналогичен fmap, только возвращается результат выполнения блока:

Some(1).bind(&:to_s) # => '1'
Some(1).bind { |value| Success(value) } # => Success('1')
None().bind(&:to_s) # => Nothing


В руби нет монад из коробки, но существуют гемы, которые реализуют монады:

* dry-monads
* kleisli
* tomstuart/monads

Советую dry, как единственную поддерживаемую. К тому же, при использовании dry-validation можно легко конвертировать результат валидации в монаду, воспользовавшись экстеншеном:

Dry::Validation.load_extensions(:monads)


Это минимум, который нужен, чтобы начать использовать монады в руби приложении. Для закрепления - перепишем изначальный пример с использованием монад:

http.get(url, params) # теперь клиент возвращается Result Monad
 # валидация возвращает Result, который используется для следующих вызовов
 .bind { |body| validator.call(body).to_result }
 # сохраняем в базу, если валидация вернула Success
 .bind { |payload| Maybe(user_repository.create(payload)) }
 # вызываем воркер, если сохранение вернет Some
 .fmap { |user| NotificationWorker.perform_async(user.id) }


Кроме использования монад в бизнес логике, попробуйте эту абстракцию для обработки результата, который возвращается из бизнес логики. Как пример - вызов operation из экшена и последующая обработка результата в этом же экшене: cookie_box/show.rb

Что делать с результатом

При использовании dry-monads можно:
- вызывать на прямую success?, failed? или value_or;
- использовать `dry-matcher`;
- мой любимый вариант, использовать `case`;

Минусы

1. В отличии от условий (if, unless, etc) нельзя просто взять и использовать монаду. Если не знать в чем смысл абстракции и что значат bind и fmap - будет сложно понять код, который написан;
2. Использование монад может сильно усложнить код. Спасает опыт, а опыт получается в практике;
3.  Если хотите начать использовать монады в проекте, придется прорваться через ужас в глазах коллег (причина почему я написал этот текст);

Запомнить

* Монады - абстракция для чейна вызовов функций и следованию railway programming;
* Для использования монад не нужно математическое образование. Главное понять, что монада оборачивает данные в объекты с единым интерфейсом;
* Советую начать с  - Maybe, Result и Try;
* fmap и bind - методы для чейна вызовов функций
* Чрезмерное использование монад усложняет код, будьте осторожны и подходите к написанию кода с умом;

Полезное

* Как рефакторить руби код с монадами
* Algebraic Data Types & Monads in Ruby
* Monads and Ruby
* Railway Oriented Programming
источник
2pegramming
источник
2pegramming
и майдмап для лучшего запоминания
источник
2pegramming
источник
2018 March 26
2pegramming
#quality

Backlog Grooming - понятие из scrum, смысл которого в том, что команда собирается и решает что будет делать дальше и ставит эстимейты задачам. Проводится 1-2 раза в спринт в назначенное время. Но к сожалению, у нас, в какой-то момент возникли проблемы с PR:

- Эстимейты задач ставились на угад и бизнесу было сложно планировать спринты;
- Стали появляться большие RP. Сложность ревьювинга возрастала, а качество проекта падало;
- Возникали ситуации, когда разработчик написал код, а потом оказалось, что алгоритм не верный и (или) есть решение проще. В результате чего код переписывался, а время шло;
- Время выполнения задачи возрастало, а так же (лично у меня) появляется фрустрация и прокрастинация при работе над  большими и сложными задачами;

Решение проблем оказалось банальным, появились “technical groomings” (название взято из головы, если вы знаете как этот процесс называется официально - пишите в личку).  Смысл в том, чтобы позволить технической стороне обсудить формальный алгоритм задачи, разбить задачи на атомарные задачи и заэстимейтить каждую из задач.

Формальный алгоритм

Идея в том, чтобы у разработчиков было понимание того, как задача будет сделана. Тут спасает что угодно, текст с пошаговым выполнением задачи, блок схемы или просто рисунки в блокноте. Главное, что стоит держать в голове - нет понимания бизнес цели - не будет работающего алгоритма. Поэтому не спешите и задавайте вопросы бизнесу, даже если есть хоть малейшее недопонимание задачи.

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

- 1 задача == 1 RP;
- Работающий код, потом рефакторинг;

Также, планируйте рефакторинг и закрытие технических долгов либо перед началом работы, либо после. Если одна задача из списка блокирует другую - стоит задуматься и попробовать вынести то, что блокирует - в отдельную задачу. Яркий пример такой задачи: добавить эндпоинт для фронтенда. Минимум два варианта, так решить проблему:
- 1 большой PR в котором будет и логика и эндпоинт. Много кода и сложно ревьювить;
- 2 PR-а. быстро сделать “пустой” эндпоинт для фронтенда, а потом потратить время на логику. Так разработчик разблокирует коллег, потом сделает остальную работу;
источник
2pegramming
Плюсы

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

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

Минусы

Главная проблема - трата времени на обсуждение задачи. Этого могут не понять менеджеры, которые считают “нет кода - нет работы”. Старайтесь говорить с менеджерами и объяснять смысл таких обсуждений.

Такой подход не работает в команде из одного человека. А сам процесс груминга энергоемок, поэтому не ждите, что сможете загрумить все за один день.

И  главное - груминг требует командной дисциплины.

Советы

- Ведите записи. А в конце задачи выделяйте время на обновление документации. Это поможет в поддержке документации к проекту;
- Начните с культуры и помощи коллегам. Не везде практикуются подобные обсуждения. Хотите исправить это - подойдите и предложите поговорить о задаче коллеги. После чего попросите помощи сами;
- Один груминг - одна тема. Также, желательно ограничивать обсуждения по времени и количеству участников. Не тащите команду, хватит только тех, кто будет работать над задачей;
- Делайте груминги по необходимости. Не тратьте время коллег в пустую;

Запомнить

- Технический груминг это черепаха из рассказа о зайце и черепахе. Медленно начнешь, быстрее закончишь;
- Если проблемы с ревью или этап разработки затягивается - стоит подумать об обсуждении кода перед его написанием;
- Технический груминг включает в себя обсуждение алгоритма, создание атомарных задач и эстимейты;
- Старайтесь в первую очередь разблокировать коллег;

Ссылки
- MindNode со всеми идеями
- Product Backlog Grooming Best Practices
- Версия для покета
источник
2018 April 10
2pegramming
Привет, на улице наконец-то стало тепло, поэтому радостные новости. Я наконец-то переехал на medium. Теперь все посты будут выходить там.
В течении ближайшего времени я перевезу все тексты туда, так что подписывайтесь и рассказывайте друзям:
https://medium.com/pepegramming
источник
2pegramming
На прошлой неделе провел вокшоп в питере, спасибо ребятам из @saintprug за теплый прием. Поэтому сегодня - мысли и советы, как сделать что-то подобное. Хочется верить, что в будущем в россии будет все чаще и чаще встречаться такой формат (организаторы конференций - это ваш шанс 😉).

https://medium.com/pepegramming/workshop-adbe753f2df4
источник
2018 April 12
2pegramming
Стоит ли использовать еще одну платформу для текстов, кроме медиума?

Да, телеграф – 93
👍👍👍👍👍👍👍 49%

Нет, медиума хватит – 88
👍👍👍👍👍👍👍 47%

Да, свое (напишу @davydovanton лично) – 5
▫️ 3%

Да, яндекс дзен – 3
▫️ 2%

👥 189 people voted so far. Poll closed.
источник