-
Подтвеждение кук
В интернете новая болезнь. Сайты уведомляют, что намерены прислать куки и спрашивает, согласен ли я. Не знаю, кто это выдумал и внедрил, но у тех людей рак мозга.
Интернет существует лет эдак 30, и все это время сервера спокойно отправляли куки. Поздно вы, ребята, спохватились! Уведомление об отправке кук выглядит так же дико, как уведомление о загрузке изображений.
Понятие кук носит технический характер и не имеет отношения к потребителю. Зашел американец на новостной сайт почитать о выходках Трампа – а ему плашка на весь экран. Подтверди прием кук. Это же свинство. Куки совершенно не в мире потребителя.
Запрос о куках плох тем, что сайт выполняет не свою работу. Контроллировать куки должен браузер. В любом современном браузере можно настроить правила. С каких сайтов принимать, с каких нет, а где спрашивать подтверждения. Заинтересованный человек настроит самостоятельно.
Если я нажму “не принимать”, то как удаленный сервер запомнит мой выбор? Правильно – положит мне куку со значеним “не принимать”. То есть нарушит обещание! Или запишет флаг в localStorage, что одно и то же.
Несколько выводов из абзацев выше:
- Не нужно грузить людей ложной заботой о безопасности.
- Не стоит влезать в чужую зону ответственности.
- Нарушение этих правил приводит ко лжи.
-
Рассказ о Емаксе
В прошлый четверг я рассказывал аудитории Хекслета про Емакс. Представляю читателям блога скомпилированную версию выступления. Рассказ пересекается с прошлой заметкой о Емаксе.
Сказанное ниже носит общий характер. Это не мануал и не инструкция с шагами что скачать и куда положить. За этими вопросами пройдите по ссылкам в конце.
Кадр из фильма Трон: наследие. Хакер взламывает кого-то при помощи Емакса. Ему помогают запущенный тетрис и игра-головоломка о перестановке пирамиды.
Содержание
- Историческая часть
- Отличие от Вима
- Философия Емакса
- Недостатки. Когда не следует использовать Емакс
- Достоинства
- Как я переходил на Емакс. Трудности, мотивация
- Установка
- Основные положения
- Конфигурирование
- Коротко о пакетах
- Сборки, форки
- Для чего я использую Емакс
- Ресурсы
Историческая часть
Емакс – это старенький текстовый редактор. Ричард Столлман начал работать над ним примерно 40 лет назад. Задумайтесь, как это много – больше, чем средний возраст популярных ресурсов. Емакс – одна из самых старых программ в айти-индустрии и все еще остается в строю.
Первоначально это были отдельные скрипты на Лиспе для операций с текстом. Позже Столлман оформил их в отдельную программу. Емакс состоит из двух частей. Это маленькое ядро, написанное на Си. Ядро отвечает за ввод-вывод и отрисовку окон. Вторая часть – код на Лиспе для манипуляции с текстом.
В Емаксе используется собственный диалект Лиспа, называемый Elisp (не путать с EMACS Lisp – это совсем другой диалект). Столлман отверг Common Lisp как излишне усложненный диалект, а Scheme – как недостаточно мощный. Так появилась своя реализация.
Технически Elisp имеет серьезные ограничения – никакой многопоточности, нет хвостовой рекурсии, трудности с замыканиями. Производительность его очень невысока, примерно как Питон или Руби старых версий. Однако, даже при всех недостатках языка в нем можно творить потрясные вещи – редактировать код, управлять процессами, читать новости, RSS, играть в игры и так далее.
Известная шутка о том, что емакс – это операционная система, в которой нет нормального редактора, косвенно права. Емакс можно рассматривать как рантайм программ, написанных на ELisp. Примерно как Хром – среда исполнения Джаваскрипта.
Емакс обязан успехом исключительно Лиспу. Многие пакеты были написаны 10-20 лет назад, но по-прежнему разрабатываются, проходят рефакторинг.
Подобно Лиспу, у Емакса есть форки и ответвления. Так, в девяностых годах обанкротилась компания Lucid, программисты которой использовали Емакс. Они взрастили внутри компании независимую версию редактора. Случилось так, что разработчики не договорились о правах и лицензиях. Так появился XEmacs – своего рода улучшенный Емакс. О форках я расскажу ниже.
Подведя черту, можно сказать, что Емакс прошел сорокалетний путь развития и активно используется программистами сегодня. За этот срок написаны сотни статей, десятки книг и мануалов. Начать пользоваться Емаксом легко – в него встроен хороший туториал, на борту большой раздел документации.
Отличие от Вима
Эти два редактора часто сравнивают друг с другом. Между ними много общего, но есть и расхождения. Так, оба редактора поощряют отказ от мыши, слепой набор, автоматизацию действий, не привязывают к конкретному языку, как ИДЕ.
Различия скорее идеологические. Вим следует философии Юникса, стараясь делать одну задачу, но хорошо – редактировать текст. За счет режимов и общей механике большинство операций в Виме делаются быстрее. В каждом режиме клавиша имеет разную функцию. Комбинации становятся емче, нужно меньше клавиш, чтобы задать комбо.
В Емаксе нет режимов из коробки, поэтому комбинации нуждаются в дополнительных клавишах (Комманд и Мета), чтобы различать ввод текста и команды. Это делает комбинации не такими быстрыми в наборе.
Емакс не ограничивает себя только набором текста, наоборот – берет на себя самые разнообразные задачи, иной раз абсурдные. Каждый должен сам провести грань – что отдавать на откуп Емаксу, а что – системным утилитам.
Субъективно, Емакс пребывает в более вменяемом состоянии, чем Вим. В сообществе последнего сильны настроения в духе “взять все и переписать”. В Емаксе такого нет. Существуют Емакс-пакеты, которые очень точно воспроизводят принципы работы Вима – режимы, комбинации, исполнение Вим-скриптов.
Философия Емакса
Емакс создавался для того, чтобы редактировать текстовые файлы. Однако из-за Лиспа и развитой подсистемы ввода-вывода вышло так, что Емакс прекрасно работает с текстом в широком смысле, неважно откуда он поступает.
Это значит, Емакс одинаково хорошо обработает текст, который пришел из сети или от стороннего процесса. Поскольку в Юникс-среде основной способ передачи информации – текст, Емакс хорошо подходит для интеграции с системой. Само собой вышло так, что в Емаксе можно выполнять разные задачи, которые только косвенно связаны с текстом.
Недостатки. Когда не следует использовать Емакс
Емакс не идеален. Вот в каких случаях я не рекомендую его использовать.
-
Вам нужен редактор для разовых нужд, в основном копи-пасты. В этом случае прекрасно подойдет Саблайм.
-
Вы пишете на языке-платформе, неотделимой от ИДЕ. Например, C# или Java. Пытаться доработать любой другой редактор бессмысленно.
-
Порог входа выше, чем у стандартных редакторов.
-
Для комфортной работы редактор нужно настроить. Настройка может длиться годами. Главное – не увлекаться.
Достоинства
-
Работает в разной степени со всеми известными языками и технологиями.
-
Очень гибкая система обработки текста
-
Мощная поддержка процессов. Простота интеграции с любым системным процессом или утилитой, например, git, docker, psql, grep, ls и т.д.
-
Конфигурирование всего и вся
-
Встроенный терминал, ssh-клиент, почтовик, браузер и масса других утилит
-
Золотые хиты детства – змейка, тетрис!
M-x snake
иM-x tetris
-
Единообразие. Каждый буфер, неважно, файл это или список процессов, подчиняется основным правилам навигации и поиска. Например, вы выполнили поиск в файле, открылся новый буфер с результатами. Теперь вы можете искать в буфере результатов, словно в файле! В любом буфере, неважно, файл это или что-то другое, можно настроить правила подсветки строк. Везде одинаковая навигация, копирование и вставка. Это дико удобно. Напротив, в стандартных ИДЕ каждое окно живет по своим особым правилам.
Как я переходил на Емакс. Трудности, мотивация
Я работаю в Емаксе третий год. Расскажу, как как пришел в него и с какими трудностями столкнулся.
Мой Емакс сегодня. По клику большая версия. Слева – дерево файлов, посередине – эта статья в процессе подготовки, справа – код на Схеме.
Давно я использовал Пайчарм, поскольку основной мой язык – Питон. Затем переключился на Саблайм. Довольно быстро раскачал его плагинами и работал на равных с теми, кто остался в ИДЕ.
Зачем нужен был этот дауншифт? Пытался обозначить список необходимых вещей. Когда у тебя комбайн с сотней функций, трудно понять, что именно из этого нужно. Принцип минимализма – убираем все, затем понемногу добавляем нужное.
В случае с Саблаймом выяснилось, что для комфортной работы достаточно 5-6 модулей для нескольких языков, интеграции с SVN и Git. Саблайм я до сих пор считаю программой высочайшего уровня и рекомендую как легкую замену ИДЕ.
Но вот что беспокоило – все авторитетные для меня инженеры работали либо в Виме, либо в Емаксе. Причем вообще без вариантов (чаще – в Емаксе, но не суть). Это легко выяснить из интервью, статей, или просто посмотреть dotfiles на Гитхабе. Так, Емаксом пользуются Гвидо ван Россум (создатель Питона), Джо Армстронг (Эрланга) , Линус Торвальдс (линукса и Гита), Тед Дзюба (предприниматель из Долины). Армин Ронахер, чей вклад в Питон неоценим, используем Вим.
Полагаю, у названных людей есть деньги чтобы купить лицензии на нужные ИДЕ, но они этого не делают. Линус как-то сказал, что готов купить любую ИДЕ, но его пальцы уже нельзя переучить после 20 лет Емакса. Гвидо положительно отзывался о Пайчарме, но добавил, что опять пришел к связке Емакс + pdb (самый базовый отладчик).
Я пришел к нескольким выводам. Во-первых, ИДЕ действительно помогает на раннем этапе карьеры. Но на уровне упомянутых программистов это уже не играет особой роли. Они создали языки и компиляторы без коммерческих средств с месячной подпиской.
Во-вторых, ИДЕ – это прежде всего бизнес. Адепты Джет-Брейнс расскажут, что без ИДЕ код пишется плохо, нарушаются бизнес-процессы и страдает бизнес. Их позиция ясна.
Как показывает практика, компания оставляет за собой право сменить лицензию. Недавняя шумиха вокруг Джет-Брейнс это доказывает. Я положительно воспринимаю идею платной подписки, но лишь для тех вещей, которые работают как черный ящик. Например, Фотошоп и облачные хранилища. Но текстовый редактор – последний рубеж. Он должен быть всецело моим, и точка.
Наконец, бывают особо критичные случаи, когда без ИДЕ человек оказывается совершенно проф-непригоден. Один коллега в проекте впал в амнезию, когда Пайчарм не смог открыть по клику исходники одного хитрого модуля. Другие не мыслят себя без подсветки и автодополнения. Это полезные вещи, но плохо, когда они становятся зависимостью.
Я решил переходить на Вим или Емакс, чтобы повысить уровень.
Если коротко, с Вимом не пошло. Занимался им две недели, было страшно медленно. К концу второй недели я более-менее им овладел, но отходняк был тяжелый. У меня нет никаких претензий, возможно, я что-то не так делал или взялся за слишком трудные мануалы. По крайней мере, выучил основные команды и могу править конфиги на серверах. В будущем планирую второй заход в Вим.
Напротив, с Емаксом пошло проще. Возможно, благодаря
cua-mode
. Это такой режим для новичков, когда основные команды вроде копирования и вставки работают как в классический редакторах. Долгое время я, за годы привыкший кCtrl-X/C/V
, использовал эти же комбинации. Потом перешел на общепринятые в Емаксе.Установка
-
Для Мака. Либо скачать графическую версию, либо поставить консольную версию из brew, предварительно обновив формулы.
-
Для линукса. Из пакетов: apt-get, yum.
-
Для Винды. Скачать бинарники. На винде осложнения в том, что Емакс нуждается в стандартных Юникс-утилитах ps, grep, find. Понадобится какой-нибудь Cygwin или аналог.
Пакет для интеграции с Гитом под названием magit требует Емакс не ниже 24.4. Это не очень хорошо, так как в старых Убунтах в пакетах указан 24.3. Приходится заморачиваться со сторонними репозиториями. Для начинающих это неважно.
Основные положения
Главная смысловая единица в Емаксе – буфер. Это место, где какой-то текст. Буфер может быть связан с файлом. Буфер произошел от принципа работы с данными на лентах. Писать каждое изменения на ленту – страшно медленно. Поэтому считывали данные в память, обрабатывали и записывали поверх.
Буфер может и не быть связан с файлом. Например, это список процессов, результат поиска в текущем буфере, греп по директории, список файлов, JSON из какого-то урла, интерактивная справка и так далее.
В момент старта Емакса появляются три стандартных буфера. Это приветствие со ссылками на документацию. Потом буфер сообщений, своего рода лог. И буфер scratch для копипасты.
Этот последний буфер особый – в нем можно выполнить любой код на Лиспе и сразу проверить, какой эффект имеет этот код.
В Емаксе используют особые сокращения для клавиш. C (командная клавиша) означает Контрол, M (мета-клавиша) означает Альт. Дефис означает одновременное нажатие. Важно помнить, что 40 лет назад клавиатуры были другие, и клавиша Command располагалась рядом с пробелом, как сегодня на Маке. Так что Столлман не виноват!
Клавиатура тех дней. Обратите внимание на расположение служебных клавиш.
Примеры:
C-x b
– нажать вместе Контрол и x, потом b – сменить буфер.C-x C-f
– нажать одновременно Контрол и x, потом одновременно Контрол и f – открыть файл.M-g g
– нажать вместе Альт и g, потом еще раз g – переход на нужную строку текущего буфера (система спросит номер).
Нажатие
C-g
прерывает ввод текущей команды.Комбинаций великое множество: одна только навигация по тексту насчитывает несколько десятков, а есть еще манипуляции с регистром, параграфами, логической структурой, специфичные для пакетов операции.
Не нужно стараться запомнить все сразу, это придет постепенно.
Чтобы эффективно работать в Емаксе, желательно освоить две вещи, о которых упоминал Кирилл в вебинаре по Виму. Первое – перенести клавишу Контрол на Капс. Это необходимо и вообще не обсуждается. Если нажимать ее в стандартном положении, рука отвалится из-за сильного напряжения в кисти.
Как сделать это в Маке, я уже писал раньше.
Второе – займитесь слепой печатью. Зайдите на сайт онлайн-тренажера. Зарегистрируйтесь через соц.сеть, чтобы накапливалась статистика. Каждый день утром 15 минут печатайте вслепую. Сначала будет бесить, но статистика покажет медленное продвижение, и это классно. Вы должны как можно скорее избавиться от стрелочек и пользоваться только центральной частью клавиатуры.
Один из графиков моего профиля. Он показывает, что скорость набора медленно, но растет.
В Емаксе нет табов для открытых файлов. Это шокирует тех, кто только начал с ним работать. Дело в том, что табы не нужны. Когда вы долго работаете, сами по себе накапливаются открытые буферы (как мы уже знаем, в Емаксе это не только файлы). Я никогда не выключаю ноут, а только погружаю в сон. К концу второго месяца в Емаксе примерно 400 буферов. Представьте, что для каждого был бы таб. Я бы просто ничего не видел из-за них.
Кстати, любителям ИДЕ посвящается – откройте 400 файлов и проверьте, как поведет себя система. У моего коллеги ноут грелся так, что обжигало руку. А Емакс потребляет 100 Мб памяти и 10% процессора.
Удивительно, но основные комбинации для перемещения по тексту работают много где за пределами Емакса – например, в Хроме, почтовом агенте Мака. В Баше по умолчанию включена раскладка Емакса.
Конфигурирование
В Емаксе настраивается все что только возможно. Существует бесконечное число конфигов, пресетов, сборок, потому что каждый делает это под себя. У опытных разработчиков на Гитхабе обязательно есть репозиторий с настройками редактора.
Не стоит допускать ошибку и разу ставить сторонние конфиги с кучей пакетов. Вы должны понимать, что происходит и как этим управлять. Вы должны знать назначение каждой строчки вашего конфига. Поэтому оптимальный путь – начать с нуля, постепенно наращивая конфиг, как жемчужину.
Конфиг в Емаксе – это файл с лисп-кодом. Внутри устанавливаются переменные, вызываются команды и подключаются пакеты. Как правило, пакеты берут всю работу на себя, нужно лишь задать им правильные настройки (флаги, пути).
При старте Емакс ищет файл
~/.emacs
. Затем –~/.emacs.d/init.el
..el
– расширение файлов на Elisp. Обратите внимание, что первый файл не содержит расширения в имени.Конфигурация не должна быть завязана на конкретную машину или файловые пути. Желательно писать ее так, чтобы было легко перенести. Как только она превысит десять строк, выносите в Гитхаб. Добавьте мейк-файл или шелл-скрипт, чтобы развернуть ее парой команд.
Вот как ставится моя конфигурация:
# Скачать репозиторий куда-то себе git clone https://github.com/igrishaev/dotfiles.git ~/somewhere # скопировать папку .emacs.d в домашнюю директорию cp -r ~/somewhere/.emacs.d ~/ # перейти внутрь cd ~/.emacs.d # поставить утилиту Cask make install-cask # установить пакеты, перечисленные в cask-файле. # переменную EMACS нужно задать, если у вас в системе несколько емаксов EMACS=/path/to/bin/emacs make install-packages
Я терпеть не могу длинных навороченных конфигураций со многими файлами. При малейших обновлениях они ломаются. Конфигурация должна быть максимально декларативной. Только список необходимых пакетов и установка переменных.
Коротко о пакетах
Для емакса написаны тысячи пакетов, некоторые из которых тянут на полноценные приложения, исполняемые внутри Лисп-машины.
Пакеты хостятся в репозиториях, у которых следующие имена –
GNU, Melpa, Marmelade
. Как правило, в конфиге указывают их все. Стандартный менеджер пакетов из поставки Емакса может устанавливать из репозиториев, но не умеет разруливать зависимости. Поэтому используют либо пакет el-get, либо утилиту Cask, как в моем случае. Это утилита на Питоне для сопровождения проектов на ELisp. В ней много всего, в том числе установка зависимостей. Она переопределяет стандартный менеджер пакетов. Вы пользуетесь как будто стандартным.Основные пакеты для Емакса без привязки к конкретным языкам:
- magit – Интеграция с Гитом
- nav – Панель файловой навигации
- auto-complete – Автодополнение из разных источников
- flycheck – проверка синтаксиса для разных языков. Обычно нужен сабмодуль для конкретного языка
- markdown-mode – Маркдаун
- nyan-mode – Нян-кот в твоем Емаксе!
- simpleclip – Облегчает работу с системным буфером обмена
- json-mode – Подсветка и валидация джейсона
Сборки, форки
Я не особо осведомлен насчет сторонних сборок Емакса. Почти все время я работал со своей конфигурацией на чистом Емаксе, чтобы понять, как все работает.
Как уже упоминал выше, существует XEmacs – альтернативная ветка Емакса. В ней больше внимания уделено интерфейсу, шрифтам и внешнему виду в целом. Большинство крупных пакетов разрабатывают так, чтобы они работали в XEmacs тоже.
Проект Эрго-Емакс ставит цель создать оптимальную клавиатурную раскладку, где наиболее востребованные функции размещены в нужных местах. Авторы полагают, раскладка повысит производительность и снизит усталость рук. На этом же сайте тусит сообщество, есть сборник рецептов, снипетов и все такое.
Наконец, существует Spacemacs – попытка взять лучшее из двух миров. Соединить механику Вима с мощью платформы Емакса. Простыми словами, это громадный конфиг с пакетами для имитации Вима.
Ставил эту сборку, но не впечатлился. Кое-где были проблемы с цветовой схемой (текст сливался с фоном), приходилось ставить недостающие пакеты. Если возможности Вима я выключил, так как не особо им владею, то что я получил в остатке, кроме нескучной темы?
Судя по репозиторию проекта, работа проделана внушительная, но я не проникся. Да и вообще, идея смешения мне не нравится. Она наивна по своей природе. Вот есть Руби и Питон, у них достоинства и недостатки. Давайте возьмем от каждого только достоинства и получим идеальный язык! Или давайте Мерседес с Ауди смешаем. Или Виндуз с Маком. Это не работает.
Сложилось впечатление, что в этой сборке выигрывает только Вимер. Для Емаксера нет ничего нового. Добавлю, любая имитация всегда отстает на шаг-два от эталона. Когда для Вима запилят новую фичу, она попадет в Spacemacs с запозданием.
Для чего я использую Емакс
В емаксе можно делать почти все, что угодно, главное – знать меру и не стать упоротым фанатом.
Надо понимать, что некоторые пакеты имеют скорее не практический, а спортивный интерес. Например, один тип написал модуль управления кофеваркой по USB. Это забавно, но не стоит воспринимать всерьез.
В Емаксе на все найдется команда.
Я использую Емакс для следующего:
-
Программирую в Емаксе на Питоне, Кложе, Джаваскрипте, Ракете, Коммон-Лиспе. В нем же ковыряю Хаскелл и Гоу. Под каждый язык – пакет или два для поддержки. Питон, надо сказать, поддерживается очень хорошо. Трудность скорее в том, какие пакеты для него выбрать из множества. Для Лиспов емакс – родная среда.
-
Редактирую структурированные файлы: Маркдаун, Json, Yaml, ini, html, css. Где не хватает коробочных средств, тоже ставлю пакеты.
-
Работаю с системами контроля версий, почти не вылезая в терминал. Смотрю диффы, блейм, логи. Делаю и мерджу ветки в Емаксе.
-
Изредка читаю онлайн-документацию во встроенном браузере EWW. Это полезно, когда не хочешь постоянно переключаться из браузера в редактор. Делишь экран пополам, в слева страничка с доками,справа код – удобно. Емакс умеет проматывать соседний буфер, не переключаясь из основного.
-
Планирую делать резолв конфликтов при мердже веток встроенным пакетом emerge. Пока что использую kdiff3.
-
Некоторое время, когда в команде пользовались джаббером, сидел из Емакса. Тоже удобно, особенно когда обсуждаешь код.
-
Пытался пользоваться почтой с помощью встроенного пакета Gnus – не пошло в силу однопоточности Лисп-машины. На проверку почты уходит до 10 секунд (у меня куча папок), за это время ничего нельзя сделать.
-
Запускаю и контролирую процессы с помощью пакета prodigy. Был проект на микросервисной архитектуре. Чтобы завести его, нужны были штук 6 фейковых рест-сервисов. Эти заглушки было удобно поднимать и гасить прямо в Емаксе.
-
Порой пользуюсь встроенным терминалом, когда лень открывать основной.
-
Иногда делаю презентации в емаксе: пишу структурированный файл в разметке ORG, который экспортируется в HTML + reveal.js. Например, вот слайды для доклада о юнит-тестах: исходник, результат.
-
Рисую ascii-таблицы в org-mode. Параметры таблицы задаются командой. Таблица ведет себя как лист в Экселе – можно перемещаться по ячейкам, добавлять и удалять строки и столбцы, сортировать, вставлять формулы. Таблица автоматом растягивается под данные в ячейках. И при этом копируется как текст. Очень удобно для документации. Руками вы ее будете рисовать час.
Пример по шагам:
M-x org-table-create
– система спрашивает размер таблицы, ввожу число строк и колонок, получаю
| | | | | | |---+---+---+---+---| | | | | | |
- Ввожу данные:
|Python |Ruby |Perl |Java |Common Lisp | |---+---+---+---+---| |1 |2 | 3 | 4 |5 |
- Нужен еще ряд? Набираю
M-x org-table-insert-row
:
|Python |Ruby |Perl |Java |Common Lisp | |---+---+---+---+---| |1 |2 | 3 | 4 |5 | | Some long test | 42 | foo | bar | Another long text|
- Все съехало, некрасиво. Набираю
M-x org-table-align
:
| Python | Ruby | Perl | Java | Common Lisp | |----------------+------+------+------+-------------------| | 1 | 2 | 3 | 4 | 5 | | Some long test | 42 | foo | bar | Another long text |
Тадам. И это даже не верхушка айсберга, а самая мелочь из того, что можно делать в org-mode.
- Возвращаюсь к нашему списку. Веду GDT – учет личных и рабочих дел. Давно хочу написать на эту тему в блог, но пока что отдельным абзацем.
Выше я уже не раз упоминал про org-mode. Это что-то вроде офисного пакета, только для Емакса. В него входит особый язык разметки, работа с таблицами, всевозможные экспорты.
В языке разметки есть особые TODO-элементы. Им можно менять состояния, причем воркфлоу вы задаете сами в шапке файла. Им можно выставлять теги, иерархию, писать комментарии и всякие другие вещи. Но главное, их можно привязывать ко времени и делать повторяющимися.
В специальном режиме
timeline
Емакс покажет задачи на временной полосе, а вам остается помечать их выполнение. При этом у вас по-прежнему текстовые файлы. Вы можете поправить все что хотите руками, смотреть дифы.Перенес все задачи в такой файл и храню его в приватном репозитории. Каждое утро смотрю, какие задачи меня ждут и стараюсь их выполнять. Задачи можно архивировать. Емакс вырезает их из файла и переносит в архивный файл с похожим названием.
Не могу расшарить свой файл, поскольку в нем немало приватных данных, но примерно это выглядит так:
** DONE Sign Contract CLOSED: [2016-03-30 Wed 12:36] SCHEDULED: <2016-03-30 Wed> - CLOSING NOTE [2016-03-30 Wed 12:36] \\ signed ** TODO Get Reports DEADLINE: <2016-06-20 Mon +3m> - CLOSING NOTE [2016-03-28 Mon 10:52] \\ got and paid :PROPERTIES: :LAST_REPEAT: [2016-03-28 Mon 10:52] :END: ** DONE IP USN CLOSED: [2016-04-25 Mon 10:00] DEADLINE: <2016-04-18 Mon> - CLOSING NOTE [2016-04-25 Mon 10:00] \\ done ** TODO Visit some secret place DEADLINE: <2016-03-31 Thu> ** DONE Sber get new card CLOSED: [2016-04-06 Wed 15:42] SCHEDULED: <2016-04-04 Mon> - CLOSING NOTE [2016-04-06 Wed 15:42] \\ got it! ** DONE Add bank account to Paypal CLOSED: [2016-03-25 Fri 15:39] SCHEDULED: <2016-03-24 Thu> - CLOSING NOTE [2016-03-25 Fri 15:39] \\ added ** TODO Sber Deposit SCHEDULED: <2017-02-06 Mon> ** DONE Phone to Office SCHEDULED: <2016-03-01 Tue> - CLOSING NOTE [2016-03-01 Tue 15:02] \\ phoned - CLOSING NOTE [2016-02-24 Wed 22:52] \\ phoned
Это бытовые дела – позвонить, подписать, сходить в Сбербанк. Все задачи группирую по крупным разделам: работа, семья и дети, бизнес, блог, сторонний проект, новинки. Почти ничего не правлю руками, все сущности создаются командами и хоткеями.
На временной линии задачи выглядят так:
Friday 10 June 2016 Saturday 11 June 2016 Scheduled: TODO Practice Typing :learning: Scheduled: TODO Listen english :learning: Scheduled: TODO Do some secret stuff Scheduled: TODO Pay for one thing Sunday 12 June 2016 Monday 13 June 2016 W24 Tuesday 14 June 2016 Scheduled: TODO Another important task Scheduled: TODO Listen english :learning: Deadline: TODO Publish announce
Чтобы успевать как можно больше дел, нужно сделать их регулярными и заставить систему тебя пинать. Способ выше очень подошел.
Ресурсы
- Официальный туториал
- Подробнейшая вики
- Блог китаянки, у которой конфиг Емакса длиной с Китайскую Стену
- Довольно свежая книжка
- Серия статей Алекса Отта
- Раздел на Хабрахабре
-
Сегодня рассказываю про Емакс
Сегодня, в четверг 9 июня, в 17:00 по Москве я расскажу про Емакс в Слак-канале образовательного проекта Хекслет.
Затрону следующие темы:
- краткая история Емакса
- основные отличия от Вима
- как я переходил на Емакс, причины и мотивация
- советы новичкам
- плюсы и недостатки
- базовые приемы работы с Емаксом
- расширенные возможности
- для чего использую Емакс
- ресурсы, книги, статьи
- заключение и вопросы
Общение займет ориентировочно 2 часа. Позже дамп беседы выложат в архивную Вики, а я оформлю в блоге отдельным постом.
Заходите, будет интересно.
-
Доклады с шестой встречи глубокого рефакторинга
Провели шестую встречу!
Юра Хрусталев рассказал, как мы в проекте внедряли Ансибл:
Миша Вьюков дал советы как продвигать продукты и сообщества в социальных сетях.
Напомню, сообщество тусит в группе Фейсбука. Скоро анонс седьмой встречи. Принимаем заявки на доклады.
-
Размышления о Питоне
Я программирую на Питоне шесть лет. За это время назрели некоторые мысли насчет языка и его роли в ай-ти. Я решил, что следующим погружением на несколько лет будет что-то функциональное. Зафиксирую соображения, пока не утратил контекст.
Ниже – попытка обозначить слабые и сильные стороны Питона. Постараюсь, чтоб не было банальщины в духе “много библиотек и широкое комьюнити”. Все сказанное – исключительно личное мнение, которое не навязываю никому.
Итак, преимущества:
Питон – коммерчески успешный язык
Приятно осознавать, что Питон используют не только в академических и любительских кругах, но и в бизнесе. Компании доверяют ему деньги. Много фирм используют Питон – Гугл, Пейпал, Инстаграм, НАСА.
Питон создает рабочие места. Вакансий много, в том числе и в России. Питон – промышленный язык. Он стоит в одном ряду с Плюсами и Джавой по востребованности. Разработчик на Питоне имеет шанс попасть в настоящую разработку продукта. Это не суррогат местного потребления вроде 1С.
Питон – очень легкий язык
Вместе с тем, Питон чрезвычайно легко освоить. Основы учатся за неделю. Еще неделю займут пакеты и подготовка окружения. В итоге, меньше чем за месяц можно добиться места в проекте.
В Питоне мало сложных тем. Так я называю разелы языка, на изучении которых останавливаешься отдельно. В Лиспе один сложный момент – макросы. В Скале больше – трейты, импликты, составные объекты. В Питоне два – декораторы и метаклассы. В повседневной работе метаклассы не нужны, пожтому остатется только одна сложность. Разобравшись с декораторами, вы не встретите в языке других препятствий.
Питон сильно приблизил програмирование к людям
Я ни разу не видел, чтобы этот пункт кем-то упоминался. Питон стал языком, с которым любой инженер, ученый или технарь без навыков программирования могут решить задачи промышленного уровня. Питон – инструмент решения проблем.
Появились специальные проекты и книги, например, Python For Engineers, A Primer on Scientific Programming with Python и другие. На работе я видел скрипты на Питоне, написанные людьми, у которых все знание программирования сводилось к школьной программе. Но скрипты работали, автоматизировали труд, а значит, экономили время и деньги.
С Питоном управлять машиной стало проще. На каждую задачу найдется копипаста со Стек-Оверфлоу. Что бы ни загуглили – разбить строку, построить график, перемножить матрицы – в первых трех ссылках выдачи обязательно будет решение.
Конечно, подобный стиль простителен только не-программистам, когда важно получить результат, а не надежный поддерживаемый код.
Питон – легкий способ попасть в промышленную разработку
Напоминает тезис о том, как попасть в шоу-бизнес через постель. Если вы занимаетесь чем-то около-айтишным, например, администрированием, сетями, поддержкой, 1С или старыми языками вроде Дельфи, то Питон – счастливый билет. Из пунктов выше мы выяснили, это что легкий язык промышленного уровня. Возможно, он станет той подножкой уходящего поезда, на которую успеете вскочить, прежде чем расхочется что-то менять и превозмогать.
Абзацем выше я фактически рассказал свою историю. До знакомства с Питоном я занимался сайтами на CMS, Дельфями и 1С. Конечно, и с этим можно найти работу. Однако, именно за счет Питона я продвинулся на старой работе, потом переехал в другой город за 6000 км и попал в Датаарт. Позже нашел удаленку в Европе.
Питон поддерживает все парадигмы программирования
Питон удивидельно гибок. Его дизайн и синтаксис в равной степени поддерживают большинство парадигм. Стандартное ООП, императивный подход, процедурно-модульный, функциональный.
Каждая парадигма реализована в неполной манере. Так, в ООП нет приватных переменных и интерфейсов. Двойное подчеркивание – хак и обходится на раз. Интерфейсы пишут миксинами, но точное следование интерфейсу отследить невозможно.
Для полноценного ФП не хватает полноценных лямбд и неизменяемых коллекций. В тройке функцию
reduce
запрятали в недра стандартной библиотеки.Ленивые вычисления, декораторы и перегрузка операторов открывают пространство для интересных маневров. Питон мимикрирует под самые разные языки, например:
-
Fake Lisp – псевдо-Лисп, забавная попытка писать питонячий код S-выражениями.
-
Hask – закос под синтаксис Хаскела. Питонщикам очень полезно посмотреть, на какие ухищрения пошел автор, чтобы добиться столь точного сходства.
-
fn.py – функциональные ништяки из Скалы. Аналогично, очень интересно взглянуть, что под капотом.
Резонный вопрос, зачем такая гибкость? Мой ответ – чтобы оттачивать паттерны и подходы, расширять кругозор, принимать на вооружение лучшие практики из других языков и платформ.
Например, одна функция из Кложи, портированная в Питон, сэкономит много строк кода и избавит от досадных багов. Или, встретив новый паттерн, я пробую реализовать его в Питоне, чтобы оценить, насколько он уживается в рамках большого проекта.
Закончим с преимуществами. Питон не идеален. Вижу следующие недостатки:
Мелкие огрехи с синтаксисом
У Питона лаконичный синтаксис без лишних скобок, точек с запятой и прочей мишуры, нужной машине, а не человеку. Все же, остаются способы отстрелить ногу и проверсти час в дебаге, не понимая в чем дело.
Формирование кортежа. Может, кто-то не знает, что круглые скобки вокруг кортежа носят символический характер. На самом деле он определяется запятой. Возникает проблема кортежа с одним элементом:
foo = 1, 2 # it's tuple bar = 1, # it's tuple baz = 1 # it's int!
Забыл запятую – получил не кортеж, а число. Оставил на хвосте запятую – не число, а кортеж. Не страшно, код упадет из-за разных типов. Начнется боль, когда кортеж строк. Строка и кортеж поддаются общим операциям: итерации, доступу по индексу, срезу. Код отрабатывает без падений, но выдает неверный результат. Из-за одной запятой.
Следующий пример. Две строки подряд без запятой сливаются в одну. Это значит, кортеж
statuses = ( 'success', 'error' 'timeout', 'denied', )
вырождается в
('success', 'errortimeout', 'denied')
потому что нет запятой после
'error'
. Проверка'error' in statuses
вернетFalse
, что есть прямое нарушение бизнес-логики.Код на Питоне очень хрупкий и нуждается в обильном покрытии тестами. На шестом году работы с ним я до сих пор не уверен, правильно ли отработает тот или иной участок кода без теста.
Главенство ООП
Хоть Питон и поддерживает множество парадигм, основной остается ООП. Типичный фреймворк или библиотека – это набор классов, которые хранят состояние и меняют друг друга.
Вы когда-нибудь дебажили Джанго? Я да. Это был кастомный бекенд авторизации. Дебаг длился больше часа и напоминал БСДМ-сессию.
Объекты
Request
,Response
,User
,Session
устраивают свальный грех. Устанавливают ссылки друга несколько раз. Лезут в кэш непонятно зачем.Очень странные требования к бекенду авторизации. Метод
.get_user()
отдает объект пользователя. Потом этот пользователь где-то теряется, на него не остается ссылки. Система запрашивает метод.get_user_by_id()
. Я ведь уже отдал пользователя, дубина! Значит, нужно или снова лезть в базу или сеть, либо хранить в классе словарик, что не тред-сейф.Почему-то в Кложе с ее неизменяемыми коллекциями мне ни разу не приходилось лазить в сессию, реквест или респонс задним числом и что-то там править. Изменения в коллекции прокидываются только вперед.
Я не призываю программировать в сплошном ФП-стиле. Признаться, все эти статьи в духе “Программирование на Питоне в функциональном стиле” выглядят жалко. Совершенно за уши притянуты редьюсы и трехэтажные лямбды. Такой код не уживается в рамках проекта и будет выпилен, даже если его удастся как-то протащить.
Это наносит урон функциональному программированию. Распространяется заблуждение, что ФП – это мапы и лямбды.
В Питон было бы неплохо добавить что-то, что поощряло отказ от состояния. Например, неизменяемый словарь, больше функций для работы с коллекциями.
Впрочем, это был бы уже совсем другой язык.
Низкая скорость
Еще год назад говорил, что это не недостаток вовсе. Память дешевая, хостинг недорогой и прочие отмазки. Сегодня считаю такой ответ уделом дилетанта.
Скорость исполнения важна. Представьте, весь ваш софт на компе написан на Питоне. Он бы работал раз в 20-30 медленней, об играх и фотошопах пришлось забыть. Это не просто шаг назад, а откат на несколько поколений.
Недавно мне нужно было парсить лог Nginx, Гугл выдал утилиту ngxtop. Я не посмотрел, на чем она написана, поставил из пакетов. Лог в несколько гигабайт она обрабатывала час. Оказался Питон. Утилита на Си распарсила за 5 минут. Неверный выбор стоил потери времени.
Питон долго брал скоростью разработки. Да, работает медленней, зато выкатим раньше, чем конкурент на Джаве. И вот появляются языки, которые совмещают скорость кода и скорость разработки. Если писать на
X
иY
по времени примерно одинаково, аY
исполняется быстрей в 5 раз, зачем братьX
?Насчет дополнительного железа. Говорить, что поставить вторую ноду – плевое дело может лишь тот, кто пишет код и не притрагивается к деплою. Несколько нод – это распределенная система. Нужен балансировщик, разделение логов, проблемы синхронизации, согласованные обновления.
В моем личном проекте долго жил Питон, нагрузка постоянно росла. Сервер задыхался, я не успевал поднимать тарифный план. Затем плюнул и переписал на Кложе. Не забуду это чувство, когда график CPU упал с 80 до 20 процентов.
ГИЛ
На упрек в адрес ГИЛа отвечают в духе “он вам не нужен”, “используй процессы”. Так говорил и я до тех пор, пока не познал, как работает многопоточность в функциональных языках.
Мы запускаем веб-приложение на Питоне под uWSGI так. Стартует мастер-процесс. Он управляет воркерами – процессами, в каждом из которых веб-приложение. Единовременно запущены 16 Джанг, каждая из которых отвечает, когда другая занята.
Мастер-процесс следит, чтобы все были равны. Убивает тех, кто не отвечает, выжрал слишком памяти или перетрудился – выработал лимит запросов.
Я считаю этот способ уродливым. Во-первых, налицо недоверие к технологии и ее нестабильное поведение. При длительной работе процессы текут, даже мастер-процесс. Это значит, систему нужно перезапускать.
Распараллеливание на процессах лишает общего доступа к памяти, вынуждая использовать суррогаты вроде Memcache или Redis, в то время как самый эффективный кеш – общая память.
Мастер-процессы вроде uWSGI и Green Unicorn – дополнительная прокладка в цепи, по которой проходит запрос. Лишний I/O, точка логирования и падения.
Наконец, с ГИЛом нельзя ничего распараллелить, разве что запросы в сеть. Функциональные языки лишены этих недостатоков. Неизменяемость коллекций в Кложе, система каналов в Гоу позволяют рулить многопоточностью без страха отстрелить ногу. Это выкашивает целый пласт инфраструктуры: костыли в виде очередей, воркеров и крон-скриптов. И дополнительные системы, чтобы все это поддерживать.
Трудности распространения
Приложение, написанное на Питоне, трудно распространять. Маленький скриптик требует интерпретатор определенной версии, виртуальное окружение с кучей библиотек. На вопрос, как перенести окружение на машину пользователя, нет точного ответа.
Несколько лет назад я пробовал различные упаковщики:
Py2Exe
,PyInstaller
,CxFreeze
. Собрать без ошибок приложение под Винду смог только последний. Сделал это очень хорошо: выдал *.msi-инсталлятор, зарегистрировал системную службу. Но времени на сборку и чтение доков ушло немало. Почему разработчики Питона не озаботятся тем, чтобы включить в коробку систему распространения конечного продукта?Чтобы написал скрипт, запустил сборку и получил архив с исполняемым файлом. Почему функциональные языки это умеют, а Питон – нет?
Кложа выдает uberjar. Собираю его на Маке, загружаю на хостинг, где кроме Джавы ничего нет – работает без проблем. Хаскель компилируется в бинарь. Ракет, Раст – тоже. Коммон Лисп, которому тридцать лет, Карл, делает дамп Лисп-машины в бинарный файл!
Фактически, чтобы запустить веб-приложение на Питоне, нужно иметь примерно 10.000 *.py-файлов. Если не будет одного, система не заведется. Изолировать это многообразие можно Докером, но здесь мы кривим душой.
Листая документацию к третьему Питону, обнаружил занятный модуль zipapp. В первую минуту подумал, что напрасно упрекал язык, дело сдвинулось с мертвой точки. Оказалось, модуль не поддерживает виртуальное окружение и сишные библиотеки. Собрать простое приложение с драйвером Постгреса я не смог.
Заключение
Такие получились пункты. Надеюсь, никого не обидел критикой в адрес языка.
Ничуть не жалею, что потратил на Питон столько лет. Пусть следующий язык внесет в мою жизнь не меньший вклад.
-
-
Комментарии к статье о Лиспе
Прочитал статью Лисп – философия разработки от 2010 года. Решил законспектировать заключительынй раздел с выводами – очень уж понравились.
Если рассмотреть каждый отдельный язык, то, как правило, можно найти его объединяющую идею. […] Для Common Lisp объединяющей идеей на данный момент является как раз расширяемость.
Не могу с точностью судить о CL, но расширяемость в Кложе(скрипте) сделана на высоте. Пожалуй, это единственная экосистема, где любой разработчик может внести свой контриб в чужой тип или протокол без обезьяних патчей, как в Руби и Питоне. Напоминает перегрузку операторов, но в масштабах всей Лисп-машины. Это надо просто попробовать.
В то же время у нее [Джавы] есть и сильная сторона, а именно пронизывающая весь язык модель семантической расширяемости через интерфейсы. Так что в общем-то не удивительно, что язык Clojure появился именно на Java-платформе…
Да, единственно хорошая вещь в ООП – это интерфейсы. Недавно я узнал, что в Кложе(скрипте) вообще все с ног до головы построено на интерфейсах. Это и придает языку такую мощь.
Объектно-ориентированный подход обещал, что базовыми компонентами повторного использования будут классы и их наборы. Однако, как показывают провалы многих технологий, таких как JavaBeans, это тупиковое направление. Ведь отдельные классы не могут быть независимыми компонентами, потому что в этом случае они рискуют превратиться либо в пространства имен, либо в монолитные монстры, противореча самой идее декомпозиции, основанной на классах.
Подпишусь всеми конечностями. Не раз видел: есть жирный класс, нужно создать похожий. И почему-то разработчик, который вчера заливал про преимущества ООП, выделяет мышкой и копипастит в соседний модуль. А как же наследование, спрашиваю я? Все понятно. Классы хоть и похожи, но приведение к общему знаменателю будет стоить так дорого, что просто невыгодно. И юнит-тестов может не хватить.
В тех же языках, где расширяемость затруднена […] есть тенденция к постепенному включению всего необходимого в стандартную библиотеку или же в какие-то крупные фреймворки, каждый из которых зачастую развивает собственный механизм подключения и повторного использования. Здесь структура зависимостей — это дерево или же несколько отдельных слабо пересекающихся деревьев.
Вспомнился бедовый Джаваскрипт. Не везет языку. При всех возможностях к расширению через прототипы, разработчики педалат тысячи микро-модулей по 10 строк каждый. Расширять стандартную библиотеку никто не думает. Так сообщество двигается в пропасть.
В этом смысле показателен пример Python, известного своим девизом «Батарейки в комплекте», который подразумевает наличие в стандартной библиотеке (почти) всего, что нужно для разработки. […] Обратная сторона медали тут отмечена в другой цитате: «Пакет, который попадает в стандартную библиотеку, стоит одной ногой в могиле»
Меткое замечание. Не случайно автор библиотеки requests, ставшей де-факто для HTTP-запросов, заключил с Гвидо неформальное соглашение. Согласно ему,
requests
НЕ включается в стандартную библиотеку (чего так хотелось Гвидо), но рекомендуется к использованию на страницах официальной документации. Хитрый мужик! Знал, чем чревато.В Common Lisp для этого [построения расширяемых систем] используются следующие технологии: макросы для создания мини-языков для декларативного описания систем, дистрибутивов (в отличие от использования для этих целей внешних языков, таких как XML)…
Да, достоинство Лиспов – всегда можно написать доменный язык под любую задачу благодаря системе макросов. В Лиспе построение XML, HTML, SQL вырождается в декларативное дерево с одноименными узлами (cdata, div, select).
Кому интересно, загляните и в другие статьи Практики функционального программирования. Актуальность они не потеряли и еще долго ее сохранят.
-
Полезные практики
Методом проб и ошибок выработал набор практик, с которыми работаю лучше. Стал допускать меньше ошибок, легче отслеживаю бизнес-логику, быстрее вношу изменения в код. Эти практики не следуют строго определенным парадигмам. Наверняка под каждую придумали паттерн, но я об этом ничего не знаю и расскажу простыми словами.
Первое. Указываю тип переменной в имени
Задаю переменным имена по правилу
<entity>_<type>
. Открыв код месячной давности, сразу вижу, где и какие типы. Даже самая коммерческая ИДЕ порой не может понять, с чем имеет дело. А с моим правилом именования работать одно удовольствие.Применяю его не слепо, а выборочно. Скалярным типам, например, строкам и числам, не указываю тип, если он ясен из контекста. Выражения
name_str = 'test'
илиage_int = 42
избыточны, поскольку имя и возраст вряд ли могут быть чем-то отличным от строки и целого.Я добавляю в конце тип, если он неочевиден из контекста. Предположим, из ответа чужой апихи пришло поле
permission
. Что это – строковое имя, числовой код, булево – понять со стороны невозможно. Все, что я могу – слазить в документацию или промотать в другое место, чтобы увидеть, что с этим полем делают дальше.permisson = response['data']['item']['permisson'] # wtf is permisson?
А ведь достаточно назвать переменную
perm_int
, и все станет ясно – это же числовой код!Указывать тип стоит везде, где кроется неожиданность. Айдишка объекта может быть передана строкой, поэтому назову переменную
user_id_str
, а дальше преобразую в инт. Поле может называтьсяitem
, а внутри – гуид сущности, а не словарь. И так далее.Коллекциям задаю тип без исключений. В Питоне достаточно много разных коллекций. Чаще всего нас интересует только итерация, но шаг в сторону, и программа падает.
Примеры? Хотели список, чтобы изменять элементы, а пришел кортеж. Итерация по множеству проходит в разном порядке. Хеш от списка вызывает исключение. Пройтись по итератору можно только один раз. И так далее.
Если работаю со словарем с данными о пользователе, называю
user_dict
. Список пользователей –user_list
, множество –..._set
и так далее, принцип, думаю, понятен. Для кортежей и итераторов окончанияtupl
,iter
.Отдельно стоит упомянуть тип
Queryset
, с которым постоянно работаешь в Джанге. Обозначаю его какqs
. С этим типом сплошная беда. Он всеми силами мимикрирует под список и кидает в неподходящий момент.Смотрит коллега в монитор и не понимает, отчего Pytest падает и выводит следующее:
assert [1L, 2L, 3L] == [1, 2, 3] >>> long trace...
Потому что справа список, а слева – квери-сет. Он выводится как список, но не равен ему.
Отдельным абзацем замечу, что не приемлю лексемы
data
в именах переменных.user_data
,response_data
– ужасные имена. Любая переменная, даже ноль, уже несет данные. Понятней не стало. Это словарь, список или что?Добавлять на конце
s
тоже нет смысла. Коллекция подразумевает больше одного элемента. Если не указан тип, я опять в беде:users
– это сет, словарь или кортеж? Можно ли брать слайс? Подставить в ключ словаря?Падение на
None
(он жеnil, null, undefined
, etc) – особая история. В программировании до сих пор нет понимания, что делать с пустыми типами. Чтобы обезопасить код, полезно явно задать имя вродеuser_or_none
или, для краткости,user_none
. Это вынудит программиста выполнить проверку перед тем, как что-то делать с данными.Второе. Избегаю циклов
О вреде циклов я уже писал, и не раз. Если коротко, то:
- ручное накопление списка или словаря чревато багами
- со временем цикл разрастается, обрастает вложенными
for, if
- из-за отступов плохо видно бизнес-логику
- цикл поощрает плохую практику – впендюрить
continue
вместо того, чтобы отфильтровать данные до входа в цикл - цикл плохо поддается рефакторингу, поскольку затягивает контекст – коллекцию-результат, локальные переменные, вложенные циклы.
Решение – использовать функции высшего порядка
map
,filter
. Я отрицательно отношусь к трехэтажным лямбдам. Использую обычные функции, объявленные черезdef/func/defn
.def get_item_list(user_id): def get_item(product): ... item_qs = models.Item.objects.filter(user_id=user_id) return map(get_item, item_qs)
Я просто объявляю функцию в том месте, где она нужна, и не парюсь за производительность или дзен. Код становится на рельсы: коллекция –> фильтрация –> действие –> другая коллекция –> свертка. Появляется ощущение структуры программы, приходит упорядоченность.
Добавить новое бизнес-правило в такой код очень легко. Это будет или еще один фильтр, или изменится действие над элементом. В любом случае не съедет весь код, как в примере ниже:
items = users.get_items() res = [] for item in items: if items.color = 'red': continue res.append(item.id)
Приходит эффективный менеджер и говорит, что теперь операция должна выполняться по всем юзерам. Не вопрос, отвечает программист и тупо сдвигает табом:
res = [] users = get_all_users() for users in users: items = users.get_items() for item in items: if items.color = 'red': continue res.append(item.id)
Дифф покажет полную замену кода. Добавить сюда еще пару вложенных условий, перехват ошибок, запись в лог – и код останется выкинуть на помойку.
Простое правило “дейтвие, коллекция, мап, свертка” работает без нареканий и легко адаптируется под новые требования.
Третье. Отлавливаю ошибки как можно раньше
Почти любая операция небезопасна и может кинуть исключение. Проблема в том, что одновременно писать бизнес-логику и следить за ошибками трудно. Каждая ошибка – это блок
try-catch
и запись в лог, за которыми не видно главную мысль.Исключения уже вовсе не означают исключительную ситуацию. Они стали сигналами. Тот же Питон кидает и сам отлавливает определенные исключения в ходе работы. Эта практика перешла и в бизнес-логику. Например, когда нет прав на операцию, выбрасывают исключение
PermissionError
. Обработчик сверху ловит его и выводит адекватный результат.Мне не нравится эта ситуация, потому что она ненадержна. Язык не может внятно сказать, какие исключения возникают при конкретной операции. Это может быть описано в документации, но чаще всего выясняется эмпирически.
Не отлавливать свои же исключения неправильно с этической точки зрения. Ты словно говоришь коллегам – вот написал код, но меня не волнуют ошибки. Да, упадет, если в ответе нет ключа. Но ты оберни и залогируй. Превозмогай, это не мои проблемы.
Заворачивать весь код в
try-catch
– не выход. Поможет возврат пары, как в Golang. С небольшим отличием – не(ok, result_or_error)
, как принято в последнем, а(err_or_null, result_or_null)
, как в Node.js. Второй вариант логическии правильней.Заворачиваю функцию в простой декоратор:
def err_result(f): def wrapper(*args, **kwargs): try: return None, f(*args, **kwargs) except Exception as e: return e, None return wrapper
Или вызываю just-in-place:
def some_func(foo): ... err, result = err_result(some_func)(42)
Вариант с мапом. Функция-обработчик раскладывает пару на составные части с помощью деструктивного синтаксиса:
item_queryset = models.Item.filter(...) def process_item(item): ... pair_list = map(err_result(process_item), item_queryset) def process_pair((err, result)): if result: # positive brunch if err: # negative brunch map(process_pair, pair_list)
Или отделяю котлеты от мух: разбиваю список пар на плоские списки ошибок и результатов. Отдельно логирую ошибки. Передаю результаты на дальнейшую обработку. Так в коде появляется порядок.
Конечно, в случае с одноразовым скриптом я могу завернуть все в глобальный
try-catch
. Но прекрасно отдаю себе отчет в том, какие последствия это имеет в боевом коде.Заключение
Вот такие принципы я проповедую в текущем проекте. С ними стало работать легче. Меньше падений на типах, внезапных трейсов.
Повторюсь, описанные принципы не идеальны, но с ними возникает чувство порядка. Словно код становится на рельсы, а вместе с ним и процесс. Возникает линейность, предсказуемость действий.
Кто-то скажет, что это не питоник-вэй, что диктатор не велел. Но кому это интересно? Мы пишем код не для Гвидо или Торвальдса, а для начальников, которые в гробу видали все паттерны, главное, чтобы код работал.
Допускаю, что прочту этот пост через 2 года и подумаю, каким чудаком я был, но пока что так.
-
Полезный сервис Requestb.in
Наткнулся на полезный сервис Request Bin.
Частенько бывает, какой-нибудь Твиттер, Фейсбук или Пейпал пингуют ваше приложение. Шлют нотификации о платежах, событиях. Проблема, что приложение еще не на сервере, а интегрироваться как-то нужно.
В документации стороннего сервиса часто описаны не все возможные случаи. Приходится закачивать скрипт-заглушку и писать запросы в файл. Это не то.
Поможет Request Bin. Идея сервиса гениальна. Вам дают уникальный урл, например,
http://requestb.in/1j2bq6r1
. На все обращения сервис отвечает 200 ОК, а сам записывает входящий запрос в память. По адресуhttp://requestb.in/1j2bq6r1?inspect
сервис покажет последние 20 запросов: дату, метод, заголовки, параметры.Полученный урл указываем в настройках стороннего сервиса. Выполняем операции, смотрим, какие запросы пошли.
При бесплатном использовании запросы хранятся в мемкеше, поэтому в любой момент данные можно потерять. Впрочем, мои запросы хранятся уже третий день.
Request Bin поддерживает соединение по протоколу HTTPS, правда, с самоподписанным сертификатом. Это помогло при интеграции с Пейпалом. Последний требует, чтобы урл начинался с
https://
, но не проверяет сертификат.Сервису есть, что улучшить. Если в теле запроса был json, парсить и показывать красиво. Сейчас выводит как пришло – в одну строчку. Добавить экспорт запросов в любой формат. Показывать сырой запрос (т.н. raw HTTP).
-
Доклады с пятой встречи любителей рефакторить
Провели пятую встречу!
Я рассказал про тесты с фикстурами:
Михаил Хорпяков объяснил, какие вопросы задать работодателю на собеседовании:
Напомню, сообщество тусит в группе Фейсбука. Скоро анонс шестой встречи. Принимаем заявки на доклады.
-
Читаю интернет в Киндле
Нет, это не про встроенный в Киндл браузер. Я продолжаю эксперименты с читалкой, купленной три месяца назад. Пытаюсь понять, как с ее помощью навести порядок в чтении.
Раньше, найдя в сети большую интересную статью, терялся от незнания, что с ней делать. Читать сейчас – времени нет. Держать открытой вкладку? Уже 20 открыто, куда больше. Остается жать “Добавить в избранное” и забывать о статье навсегда.
Статья в избранном – это закрытая вкладка. Энтропия и шум настолько сильны, что по факту к статье вы не вернетесь.
День за днем растут списки “прочитать позже”. Когда открываешь наконец что-то из списка, понимаешь, что на сегодня уже выработал потенциал. Все, на что тебя хватит – пара линков из чата со смешными картинками.
Кто-то шлет интересные статьи себе на емейл. Как Столлман, но тот всего лишь боится проприетарного JS-кода. Уже лучше, чем закладки: централизованное хранилище, доступ с любого устройства, сносная поддержка мультимедии.
По моему опыту долгое и плодотворное чтение за ноутом невозможно. Ноут – это инструмент для работы и коммуникаций, а чтение – удовольствие для себя. Поэтому, когда садишься с читалкой, мысленно соглашаешься с тем, что сейчас твое время. А за ноутом сто раз отвлекут коллеги.
Кинлд помог разрешить этот вопрос. Ключевая особенность Киндла в том, книжки закачиваются по емейлу. И не только книжки, а любые документы. Появились сервисы, которые шлют емейл с документом на емейл в Амазоне, а книжка качает из облака.
Прекрасное расширение для Хрома и Лисы закачивает любую веб-страничку в Киндл. Удаляет весь мусор, красиво компонует текст. На экране читалки смотрится изумительно.
Теперь с материалами я работаю так: листаю любимый RSS-клиент, если нахожу что-то стоящее, клик – и в Киндл. Читаю во время прогулок с сыном. Летом посидеть на лавочке с читалкой – красота. Технический минус, расширение не поддерживает картинки. Очень странно. Сделали бы премиум-фичей, я бы заплатил.
С новым подходом я прочитал замечательную статью “Being A Developer After 40”. На очереди несколько постов из блога Гвидо Ван Россума.