воскресенье, 24 октября 2010 г.

Идеальная архитектура. Ведущие специалисты о красоте программных архитектур

Идеальная архитектура. Ведущие специалисты о красоте программных архитектур // 2010
Диомидис Спинеллис, Геориос Спинеллис

Эта книга состоит из набора более или менее связанных статей, написанных различными авторами о проектах, в которых они принимали активное участие. Начинать читать можно смело со второй главы, так как первая глава - "Что такое архитектура?" - чрезвычайно разжижена досужими разговорами и абстрактными определениями не менее абстрактных понятий.

Значительную часть книги составляют статьи об архитектуре различных систем виртуализации и эмуляции: Xen (гипервизор), JPC (эмулятор x86, написанный на Java), Jikes RVM (научно-исследовательская виртуальная машина Java, написанная на Java и работающая под управлением самой же себя). Из более экзотических вещей можно отметить обзор архитектуры OpenSource фреймворка для создания онлайн (Massive Multiplayer Online) игр под названием Darkstar (опять же на Java).

Очень любопытные статьи про GNU Emacs и KDE: в них рассматриваются не только архитектурные изюминки данных систем, но и описывается социальное устройство этих известных и славных OpenSource проектов.

К сожалению, при всей своей архитектурной красоте и современности, некоторые проекты развиваются не очень активно. Так, например, обстоят дела с проектом JPC. Судя по данным с сайта проекта, полноценная поддержка (т.е. загрузка до графического режима) есть только для DOS и двух специализированных Linux-дистрибутивов (Damn Small Linux и Feather Linux). Ни Debian ни Ubuntu ни RedHat ни даже Windows XP не поддерживаются. Зато можно поиграть в старый добрый DOS-овский DOOM прямо в апплете браузера и лишний раз подивиться красоте архитектуры и смелости замысла.

С проектом Darkstar всё тоже не так гладко. Ранее этот проект поддерживало подразделение Sun Labs, но видимо в связи с недавней покупкой Sun-а Oracle-ом проект прикрыли. Не смотря на это, от Darkstar-а отпочковался проект RedDwarf, который поддерживается теперь самим сообществом.

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

Оценка по шкале ИМХО: 4

пятница, 15 октября 2010 г.

Автодополнение имён Perl-модулей в Bash

Введение

Автодополнение имён файлов и директорий в Bash - настолько удобная и полезная функция, что пальцы сами тянутся нажать на [TAB] для получения списка вариантов или точного совпадения. Это экономит массу времени и уменьшает вероятность опечатки. Однако, возможности автодополнения в Bash не ограничиваются только лишь именами файлов и директорий: по-сути, автодополнять можно любую команду причём совершенно произвольным образом.

В этой статье рассказывается о том, как научить Bash автодополнять имена Perl-модулей. Вот только несколько возможных применений этой функции:
  • Вывод документации по модулю (perldoc My::Modu [TAB] My::Module)
  • Редактирование модуля (vim Foo::B [TAB] Foo::Bar)
  • Вывод версии модуля (см. pm-version.pl)
По большей части эти преимущества оценят люди, ежедневно занимающиеся разработкой на Perl. Остальные же могут изучить этот пример и адаптировать его для своих нужд.

Получение списка модулей

Во-первых, нам понадобится скрипт, позволяющий получить имена всех Perl-модулей, установленных в системе. Для этой цели прекрасно подходит pmdesc3.pl который, кстати, входит в состав perl-support.vim - отличного VIM-плагина для Perl-разработчиков. Помимо имени модуля, этот скрипт также выводит его версию и заголовок POD документации:
./pmdesc3.pl

...
WWW::Mechanize (1.34) Handy web browsing in a Perl object
WWW::RobotRules::AnyDBM_File (5.810) Persistent RobotRules
DateTime::TimeZone (0.7701) Time zone object base class and factory
DateTime::Locale (0.35) Localization support for DateTime.pm
...
Эта дополнительная информация будет лишней при выводе списка совпадений в Bash-е, поэтому её лучше предварительно убрать:
./pmdesc3.pl 2>/dev/null | awk '{ print $1 }' > /path/to/modules.list

...
WWW::Mechanize
WWW::RobotRules::AnyDBM_File
DateTime::TimeZone
DateTime::Locale
...
Таким образом, в файле /path/to/modules.list окажется список всех установленных модулей. Этот список следует поддерживать в актуальном состоянии: обновлять cron-задачей, а также сразу после установки нового Perl-модуля (читай ниже).

Важный момент: для того чтобы скрипт pmdesc3.pl нашёл не только стандартные модули, но и модули написанные вами, следует добавить соответствующие пути к переменной окружения PERL5LIB:
PERL5LIB="$PERL5LIB:/path/to/my/lib/"
Напомню, что обычно, переменные, определённые в ~/.bashrc не наследуются cron-задачами, поэтому соответствующую переменную необходимо прописать и в crontab-е.

И, наконец, финальное замечание. Как оказалось, скрипт pmdesc3.pl не посещает директории из @INC, являющиеся символическими ссылками на другие директории. К примеру, в Debian Lenny:
$ ls -l /usr/share/perl/5.10
lrwxrwxrwx 1 root root 6 Фев 11 2009 /usr/share/perl/5.10 -> 5.10.0
Но не смотря на то, что в @INC есть /usr/share/perl/5.10, директория /usr/share/perl/5.10.0 скриптом не обрабатывается. Для того чтобы скрипт обошёл и "символические" директории тоже, добавьте их явно к PERL5LIB.

Настройка автодополнения

Механизм автодополнения работает следующим образом. Пользователь определяет специальную функцию и регистрирует её командой complete. В результате, complete связывает конкретную команду (в нашем примере их три: V, v и d) с пользовательской функцией для автодополнения (_perl_module). Почему названия команд такие странные, вскоре станет ясно. Пока же можно считать, что для лаконичности.
PERL_MODULES_LIST="/path/to/modules.list"

_perl_module() {
COMPREPLY=();
cur="${COMP_WORDS[COMP_CWORD]}"

if [[ ${cur} == ?* ]] ; then
COMPREPLY=( $(grep "^${cur}" "$PERL_MODULES_LIST" | sed -e 's/:/\\:/g') )
return 0
fi
}

complete -F _perl_module V
complete -F _perl_module v
complete -F _perl_module d
Функция автодополнения получает в качестве аргумента часть уже введённого текста ($cur) и на его основе должна сохранить в переменной COMPREPLY список вариантов. В нашем случае это результат элементарного grep-а по имени модуля плюс экранирование символа ':'. Экранирование несколько портит вид выводимой подсказки, но к сожалению без этого нельзя.

Отмечу, что более сложная функция автодополнения может использовать контекст (предыдущие введённые слова) для более интеллектуальной подсказки. К примеру, предыдущее слово можно получить так:
prev="${COMP_WORDS[COMP_CWORD-1]}"
Приведённый выше файл необходимо поместить туда, где Bash сможет его найти и загрузить. В Debian Lenny есть специальная директория для функций автодополнения: /etc/bash_completion.d/

Bash-алиасы

Алиасы d и V, упомянутые выше, названы так только для краткости. Для того чтобы они заработали необходимо добавить в ~/.bashrc следующие строки:
alias d="perldoc"
alias V="/path/to/pm-version.pl"
Скрипт pm-version.pl показывает версию модуля и сообщает является ли он core-модулем и если да, то начиная с какой версии Perl.
alias v="PAGER=$EDITOR perldoc -m"
Алиас v - немного хитрее. Он позволяет открывать Perl-модули на редактирование по имени, а не по пути, т.е. v Foo::Bar вместо vim /path/to/lib/Foo/Bar.pm

Для достижения этой цели используется малоизвестная опция -m команды perldoc. С этой опцией perldoc открывает код Perl-модуля (не POD, а именно код!) пейджером (обычно less). Подставив в PAGER ваш любимый $EDITOR, исходный код модуля чудесным образом откроется на редактирование.

Обновление списка модулей при установке нового пакета

После того как в базовом варианте всё заработает, возникает естественное желание обновлять список модулей не только по расписанию, но и сразу после установки очередного модуля.

Обычно, во всех дистрибутивах имена пакетов для Perl-модулей имеют определённую структуру. В Debian, к примеру, за очень редким исключением, пакет для Perl-модуля Foo::Bar будет называться libfoo-bar-perl. Используя этот факт несложно написать небольшую обёртку для менеджера пакетов, которая будет выполнять следующие действия:
  • Преобразование имени Perl-модуля в имя пакета
  • Установку пакета
  • Пересоздание или обновление списка установленных модулей
Интеграция с VIM-ом

Как известно, VIM имеет встроенный механизм автодополнения по словарю (CRTL+n). Таким образом, если подключить уже имеющийся у нас список модулей в качестве словаря, то можно будет автодополнять выражения вида use и require:
use Foo::B [CTRL+n]
| Foo::Bar
| Foo::Bar::Baz
Вот необходимое заклинание для ~/.vimrc:
set dictionary+=/path/to/perl-modules.list
Консольный скрин-каст: сёрфинг по Perl-модулям

Работу автодополнения наглядно демонстрирует следующий консольный ролик: surf-perl-modules.txt. Для его воспроизведения потребуется программа ttyplay:
ttyplay surf-perl-modules.txt
Приятного просмотра!

Ссылки