[Moscow.pm] Coro
Alexandr Gomoliako
zzz на zzz.org.ua
Чт Янв 19 16:25:56 PST 2012
On Thu, Jan 19, 2012 at 11:56 PM, Ruslan Zakirov <ruz at bestpractical.com> wrote:
> Покажите. Я хочу посмотреть красивый код на любой событийной либе,
> который будет иметь минимальное количество вложеных блоков, ананомных
> функций и просто будет аккуратен и читабелен. Я хочу научится.
Понимаемость и читабельность - разные вещи. Анонимные функции как раз
позволяют очень сильно улучшить понимаемость.
Вот пример http/1.0 запроса:
https://github.com/zzzcpan/nginx-perl/blob/master/src/http/modules/perl/Util.pm#L42
Можно еще глянуть на CPS:
http://search.cpan.org/~pevans/CPS-0.12/lib/CPS.pm
Наверное надо куда-то пост сделать на эту тему и развить ее немного. Пока здесь:
ПРИЧИНЫ СЛОЖНОСТИ КОДА
Вообще есть две основные причины сложности (понимаемости) кода:
- изменение состояний;
- последовательность выполнения (control);
Т.е. если состояния меняются не явно или последовательность задана
там, где она не имеет значения, то код сложный. Это еще называют
случайная сложность (accidental complexity).
СЛОЖНОСТЬ И PERL
В Perl проблема последовательности решается возвращением результата в
колбэк. Т.е. последовательность задается явно, с помощью определения
функции, куда будет возвращен результат выполнения.
А проблема неявного изменения состояний решается с помощью
использования анонимных функций в качестве этих колбэков и
использовании переменных из пэдов (closures).
И оказывается, что это все еще и идеально подходит для асинхронных приложений.
Лет 5 назад это было не очень хорошо, потому что perl сильно тек с
таким подходом. Но сейчас самое время.
Это же можно применять и в блокирующих приложениях, их будет и легче
поддерживать и потенциально возможно использовать с асинхронными.
ПРИМЕР
Вот пример. В нем порядок выполнения двух функций роли не играет и это
задано явно. А еще состояние $done меняется явно
sub foo ($&) {
my ($arg, $cb) = @_;
my $done = 0;
do_something $arg, sub {
my ($res) = @_;
&$cb ($res) unless $done;
$done++;
};
do_something2 $arg, sub {
my ($res) = @_;
&$cb ($res) unless $done;
$done++;
};
}
Подробнее о сложности кода в functional relational programming.
Подробная информация о списке рассылки Moscow-pm