Вадим Венедиктов, 29 августа 2011 года
Макс написал, как он настраивал шифрование писем для одного из наших проектов:
ActionMailer_X509: подписываем и шифруем письма прямо в Ruby On Rails
Вадим Венедиктов, 17 июля 2011 года
Отличный простой инструмент для совместной удалённой разработки: piratepad.net
Поговорите, пожалуйста, с роботом
Вадим Венедиктов, 9 февраля 2011 года
А вот пример довольно странного поведения от отечественных знатоков бизнеса. Это письмо я получил от MBA Consult
Здравствуйте!
Напоминаем, что Вы зарегистрировались на Информационную сессию Harvard Business School.
... *информация о встрече* ...
Просим Вас подтвердить участие в мероприятии, ответив на это письмо. Если Ваши планы изменились, просим Вас также сообщить нам об этом.
Ни в теме, ни в подписи не указано имени того, кто мне пишет. Письмо, фактически, анонимно. Конечно, я понял, почему оно мне пришло и зачем мне его послали, я бы слова не сказал про этого робота, если бы не одно «но».
Меня просят ответить!
Как только я начал писать ответ, я почувствовал себя глупо. Что мне написать: «Здравствуйте, робот! Приятно, что вы позаботились обо мне и напомнили про сессию…»? Вежливые компании не заставляют своих клиентов чувствовать себя глупо.
Не смотря на то, что это, безусловно, полезное напоминание было сгенерировано автоматически, организаторы могли сделать его более человечным. Роботы не ведут бизнес. В любой компании работают обычные живые люди. Почему не указать имя и фамилию ответственного лица? Например, Вячеслав Давиденко. Всем всё равно будет понятно, что этот Вячеслав не писал около сотни писем вручную. Но лично мне будет приятнее ответить реальному человеку, нежели безликой программе.
RSS-читалка Readbox.info
Петрунин Максим, 18 января 2011 года
Пару месяцев назад на хабре пропиарился сервис Readbox.info. Сервис показался интересным, хотя я так и остался на Яндекс.Подписках. Но вот уже с начала года я, незаметно для себя, полностью мигрировал на Readbox.
Причин много, но вот самые привлекательные для меня возможности Readbox’а:
- Не требует регистрации, авторизация через OpenID ЖЖ, Яндекс, Google и прочее
- Выгрузка RSS-ленты в формате fb2 для чтения на электронных книгах офлайн
- Поддержка полнотекстовых RSS, что особенно удобно при выгрузке на электронную книгу
- Встроенный в ленту переводчик бывает удобно перевести незнакомое слово
- Горячие клавиши, частью заимствованные у Google Reader’а
- Возможность не показывать некоторые ленты в общем списке так я фильтрую github’овские RSS И многое другое…
Теперь я не смотрю в ленту по каждому пришедшему сообщению, а перед поездкой на метро скидываю к себе на книжку и читаю в дороге.
Интерфейс Readbox очень удобен, скорость достойная приличная. Учитывая поддержку горячих клавиш ощущаешь себя не хуже чем на настольном приложении. Судя по блогу разработчиков сервис постоянно улучшается. Поддержка на высоте: когда я задал вопрос “как я залогинен в систему”, ответ пришёл мне email’у, а также был продублирован через jabber. Все эти сведения они постарались вытащить из моего Яндексового OpenID, попутно пообещав улучшить интерфейс в этом вопросе. Кстати, фреймворк разработки — Ruby on Rails.
Вадим Венедиктов, 31 декабря 2010 года
Собираетесь общаться с клиентами, работая в российской компании — научитесь извиняться.
Ruby Version Manager (RVM)
Петрунин Максим, 25 декабря 2010 года
RVM — прекрасный набор скриптов, который позволяет делать удивительную штуки, когда вам нужно использовать разные версии ruby.
Вообще, я давно присматривался к RVM, но отсутствие острой необходимости и отсутвие PKGUILD для ArchLinux останавливали меня. И вот, наконец, у меня дошли руки. Установка оказалась очень проста (я выбрал вариант не общесистемной установки, а на одного пользователя):
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
А после надо занести в файл ~/.bash_profile или ~/.bashrc следующую строку
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
Проверить, что установка прошла успешно можно с помощью команды type rvm | head -n1. Ответом будет нечто вроде rvm is a function.
Теперь можно воспользоваться магией rvm. Установка Ruby 1.8.7
rvm install 1.8.7
Переключиться на 1.8.7
rvm 1.8.7
Обратно на системный ruby
rvm system
Причём как только вы переключились на какую-то версию ruby, это значит, что всё, что вам нужно теперь тоже с этой версией ruby: bundler, irb, gem, rake, spork и т.д..
Есть ещё шикарная штука – файлы .rvmrc для проектов. Т.е. вы в проекте прописываете
echo 'rvm ree' > .rvmrc
И у вас по умолчанию при входе в проект используется Ruby Entherprise Edition. А в другом пропишите 1.9.2 и при переходе в его папку у вас будет 1.9.2!
А ещё есть возможность ставить gem’ы наборами и ещё куча всего!
Резюмируя, скажу, что rvm — шикарная штука. И она отлично помогает управляться с двумя нашими проектами, один под 1.8.7, другой под 1.9.2 без лишних сложностей.
Как быстро показать живой javascript пример
Вадим Венедиктов, 21 ноября 2010 года
Специально для того, чтобы один разработчик мог быстро показать какой-нибудь кусок кода другому существует Pastie и Gist.
Но периодически, заседая на официальном канале #jquery, я сталкиваюсь с необходимостью показать не только код, который вызывает у меня вопросы, но и создать работающий или, что чаще, неработающий пример. Это можно сделать с помощью JS Fiddle
Редактор HTML + CSS + JS с разметкой синтаксиса и возмжностью подгрузить часто используемые фреймворки (JQuery, Prototype, mootools) позволяет сосредоточиться только на главном: «что, собственно, не работает?».
Теги и перехватчики в Cucumber и в Rspec
Петрунин Максим, 20 ноября 2010 года
Теги – замечательный инструмент для упорядочивая сценариев Cucumber’а (или примеров Rspec’а). Вы можете давать теги всему. Вы можете метить долговыполняющиеся сценарии (примеры) тегом slow, и не запускать их в команде по-умолчанию. Вы можете, в случае с кукумбером, метить сценарии (или, кстати, целиком фичу) тегом @javascript, и они будут выполнятся с использованием текущего javascript-драйвера (кстати, эта возможность доступна из коробки).
Но самое часто-используемое – это специальная метка для того, над чем вы работаете именно сейчас. В кукумбер она доступна по-умолчанию и зовётся @wip. Там даже преднастроен специальный профиль, который переключает форматирование на более удобное и запускает только @wip-сценарии:
cucumber -p wip
Впрочем, если вам хочется только фильтровать теги, то можно воспользоваться ключём --tags: cucumber --tags wip. Пометь сценарий тегом wip можно следующим образом
@wip
Scenario: my scenario
Given ...
Подробнее о тегах в кукумбере можно прочесть в официальной вики.
Отличным дополнение к тегам в кукумбере является возможность создавать перехватчики (hooks). Можно перехватить что угодно, но нас интересует возможность перехватить выполнение сценария с определённым тегом.
Скажем, мы хотим, чтобы у сценариев с тегом @lvh-js параметр Capybara.app_host менялся на http://lvh.me:9887 (lvh.me, а также все его поддомены, ссылаются 127.0.0.1), и включался драйвер selenium. Сделать это очень просто. Для этого создаём файл features/support/lvh-js-tag.rb, и пишем туда следующее:
Before('@lvh-js') do
Capybara.app_host = "http://lvh.me:9887"
Capybara.current_driver = :selenium
end
Готово. Подробнее о перехватчиках также можно прочесть в официальной вики.
Что касается rspec’а, то там теги задаются чуть иначе. Теги могут быть представлены как строка, например, wip и как пара ключ-значение, например, speed:slow. Для того, что б пометь it\describe\context.. обычным тегом, надо добавить в в конце вызова :wip => true, если же хочется пометить парой ключ-значение, то :speed => :slow. Например:
it "my current example", :wip => true do
...
end
Теперь можно запустить на выполнение примеры только с тегом wip: rspec --tag wip.
Челимский, что кстати очень разумно, переносит документации в фичи кукумбера, поэтому подробнее о тегах в rspec можно прочесть в официальной фиче.
Вадим Венедиктов, 14 ноября 2010 года
Про изменение отношения к конкурентам:
Мы должны применять кардинально другие подходы. Они (конкуреты, прим. моё) вкладывают кучу бабла. Мы — не будем.
petRUShka, 05 августа 2009 г.
Вуху! А таксовик-то уже даже хохлы копируют. Купим их потом ;)
petRUShka, 13 ноября 2010 г.
Как правильно начинать и заканчивать работу над Rails 3 проектом при наличии тестов
Петрунин Максим, 13 ноября 2010 года
-
Начинается работа следующим образом: в двух вкладках терминала запускается
bundle exec sporkиbundle exec spork cucдля ускорения с помощью spork’а rspec’а и cucumber’а, соответственно. -
Ещё в одной вкладке запускается autotest:
bundle exec autotest. Теперь всякое моё изменение тут же тестируется. Кстати, я выставляюAUTOFEATURE=false, т.к. запускать ещё и cucumber по факту изменений кажется мне слишком дорогим удовольствием. Особенно, если он, как у нас в проекте, прогоняется целиком примерно за 5 минут. -
Далее, действуем согласно парадигме BDD. Но надо убедиться, что все команды (cucumber, rspec и rspec внутри autotest) запускаются с ключами
--drb. Для этого можно, например, погасить оба spork’а и запустить прогон тестов. Если он настроен на использование spork, то в терминал выведетсяNo DRb server is running. Running in local process instead .... -
Если какой-нибудь отдельный spec разросся (как у нас) до невероятных размеров, а надо работать именно с ним, то я гашу autotest. И во время работы запускаю только конкретный it. Делается это так: надо выяснить, на какой строчке находится этот it (или context\describe), например, 521, а после запустить rspec только для it’а на 521 строчке:
bundle exec rspec -l521 spec/model/my_model_spec.rb -
Кстати, если вы работаете с cucumber, то чрезвычайно удобная штука – это теги. По-умолчанию, есть тег @wip (work in progress). Ставите у текущего сценария этот тег и запускаете кукумбер:
bundle exec cucumber -p wip. Выполнится прогон только сценариев с тегом @wip. -
По окончании работы надо выгрузить всё в общий репозиторий. Предварительно, конечно, надо прогнать все тесты с новым функционалом (в т.ч. с тем, что внесли ваши коллеги). Для этого у нас есть специальный alias:
alias jointheranks='git pull && bundle update && rake db:migrate && rake parallel:prepare && bundle exec parallel_spec && bundle exec parallel_cucumber && git push'
Ускоряем прогон тестов для Rails + Rspec + Cucumber
Петрунин Максим, 13 ноября 2010 года
Тесты, просто чудесная вещь, но как и многое чудесное имеет свои недостатки. Главный из них – они очень долго выполняются. Сегодня мы рассмотрим два инструмента для улучшения ситуации.
Spork
Spork – это инструмент, который позволяет не перегружать тестовое окружение (например, сам Rails, rspec и прочие тестовые библиотеки, которые вы используете), всякий раз, как прогоняется тест. Вместо этого вы запускаете spork (для rspec или unit test) или spork cuc (для cucumber), дожидаетесь, пока он подгрузит окружение, и после этого запускаете ваш rspec или cucumber с ключём --drb. И они начинают гонять тесты, минуя стадию подгрузки окружения! С настройкой, вы справитесь очень легко.
Да, для Rails 3 вам понадобится rc-версия spork (на данный момент, 0.9.0.rc2), а cucumber + autotest не работают с spork’ом хотя кто-то утверждает, что всё в порядке.
Parralel_tests
parallel_tests – инструмент, позволяющий распарралелить выполнение тестов (test unit), спек (rspec) или фич (cucumber). Надо понимать, что он запускает параллельно разные файлы, но не отдельные тесты внутри одного файла. Поэтому ускорить выполнение одного большого спека вам не удастся.
Всё, что вам нужно делать, это создать БД как сказано в README, а также после каждой миграции делать rake parralel:prepare.
Запускать можно как с параметрами по-умолчанию rake parallel:spec (в этом случае количество процессов определится автоматически по числу ядер), так и указав количество процессов и путь: rake parallel:spec[4,models].
Я провёл несколько испытаний. Rspec:
$ date && rake spec:controllers && date
Сбт Ноя 13 14:53:38 MSK 2010
Finished in 58.36 seconds
350 examples, 0 failures
Сбт Ноя 13 14:55:33 MSK 2010
Итого, Rspec утверждает, что справился за 58.36 секунд, а по выводу команды date видно, что потребовалось 115. Т.е. ещё 57 секунд (которые, кстати, мог бы сэкономить spork) потребовалось на загрузку окружений. Кстати, на подгрузку окружения для команды rspec spec/contollers или для команды bundle exec rspec spec/contollers тратится около 30 секунд (на bundle на пару секунд дольше).
Посмотрим, на parallel с параметрами по-умолчанию:
$ date && rake rake parallel:spec[controllers] && date
Сбт Ноя 13 14:55:33 MSK 2010
2 processes for 16 specs, ~ 8 specs per process
Finished in 10.39 seconds
184 examples, 0 failures
Finished in 51.1 seconds
166 examples, 0 failures
Results:
166 examples, 0 failures
184 examples, 0 failures
Took 89.216297137 seconds
Сбт Ноя 13 14:57:19 MSK 2010
В первый раз я вывел весь лог, чтобы было понятно, как он выглядит, далее будет короткая выдержка.
Итого: 89.216297137 секунд по словам parralel_test и 106.0 фактических секунд (сэкономлено ~9 секунд). 89 сек – странная цифра, т.к. реальное время выполнения – максимальное из всех процессов, т.е. 51.1, что соответствует экономии в 9 секунд.
$ date && rake rake parallel:spec[4,controllers] && date
Сбт Ноя 13 14:57:19 MSK 2010
4 processes for 16 specs, ~ 4 specs per process
Took 130.743829138 seconds
Сбт Ноя 13 14:59:47 MSK 2010
А вот попытка выполнить на 4_ёх процессах (при реальных 2_ух ядрах) только ухудшила ситуацию: 148.0 – реальных секунд и 130.743829138 заявленных.
Тесты для cucumber:
$ rake cucumber
Сбт Ноя 13 15:26:32 MSK 2010
5m38.088s
Сбт Ноя 13 15:33:09 MSK 2010
Т.е. реальных 6 минут 37 секунд, заявленных 5 минут 38 секунд. Т.е., как и прежде – около минуты на подгрузку окружения.
$ rake parallel:features
Сбт Ноя 13 15:37:28 MSK 2010
Took 268.90437579 seconds
Сбт Ноя 13 15:41:54 MSK 2010
Итого – почти 4 с половиной минуты заявленны, а реальных 4 минуты 50 секунд. Т.е. выигрыш по сравнению с непараллельными тестами 1 минута 47 секунд. Кстати, при прогоне тестов с selenium реально запускаются два сервера и две копии браузера. При этом два сервера могут конфликтовать.
$ rake parallel:features[4]
Сбт Ноя 13 15:41:58 MSK 2010
Took 323.654938436 seconds
Сбт Ноя 13 15:47:39 MSK 2010
Итого на 5:20 заявленных, 5:41 реальных, что всё равно лучше, чем вообще без распарралеливания, но сильно хуже 2 процессов.
К сожалению, spork и parralel_test не работают вместе :(
Итого:
- Использование
rake specвместоrspec scec/илиbundle exec rspecувеличивает время выполнения теста ~ на 30 секунд. Кстати, parralel_test для Rspec запускаются командойparallel_specилиbundle exec parallel_spec(т.е. +30 секунд экономии по сравнению с rake). - Если используете parralel_test, то оптимальным числом процессов является значение по-умолчанию (т.е. число ядер)
- При выполнении одного теста, т.е. в рядовой работе, parralel_test не даст выигрыша вообще, а spork сэкономит по 30 секунд на прогон.
- parralel_test – отличная вещь при прогоне всех тестов перед выгрузкой коммита в общий репозиторий.
P.S. Rails 3 + Ruby 1.9.2 + rspec 2.0.1 + cucumber 0.9.3
Вадим Венедиктов, 4 ноября 2010 года
В принципе, мы здесь играем в игрушки. Но когда на странице сайта появляются логотипы Visa и MasterCard, отношение к нашим игрушкам становится более серьёзным.
Git: как перенести работу в новую ветку
Вадим Венедиктов, 1 ноября 2010 года
Допустим, вы работали в ветке master, сделали несколько рабочих законченных коммитов, а потом начали работу над какой-то новой функцией и поняли, что закончить её сегодня вам не удастся. Вы можете просто отложить работу над этим функционалом и продолжить работу в мастере:
$ git checkout -b dirty#1239
M app/views/orders/_check_form.html.erb
M ...
M spec/views/orders/new.html.erb_spec.rb
Switched to a new branch 'dirty#1239'
Вам сообщат, что все изменения, над которыми вы работали, переехали в новую ветку dirty#1239. После решетки удобно указать номер задачи в вашей системе учёта задач, например redmine. Теперь можно закоммитить изменения в этой ветке и вернуться обратно в master:
$ git commit -am "New function, refs #1239"
$ git checkout master
Switched to branch 'master'
И вы снова окажетесь на последнем рабочем коммите в корне дерева, можно делать push и pull спокойно.
Вадим Венедиктов, 25 октября 2010 года
Вчера мы с Максом нашли в одном из наших приложений ошибку, связанную с тем, что 31 октября Россия переходит на зимнее время. Зима приближается, я хочу сказать.
Вадим Венедиктов, 14 октября 2010 года
При суммарном объеме заказов от 5000 руб. до 200 000 руб. за последние 365 дней предоставляется персональная скидка, которая вычисляется по формуле
ln (Z) *6,5060407363636 - 54,4132058628328
где Z - сумма всех заказов за 365 дней, оплаченных денежными средствами, поступившими на расчетный счет интернет-ателье, без учета стоимости доставки.
— сообщение от интернет-ателье Рубашка на заказ
Это они на полном серьёзе. Жалко, что они не объяснили, что такое натуральный логарифм. Кажется, в нашем блоге пора открывать рубрику «идиоты».