— От циклов к коллбэкам
— От коллбэков к итераторам
— Борьба со сложностью, изоляция аспектов
— Гибкость и модифицируемость кода
— Преимущества и недостатки
4. open my $in, "/tmp/in.csv";
my @file = <$in>;
close $in;
corp.mail.ru
Читаем файл
5. my @out;
for my $ln ( @file ) {
chomp $ln;
my @fields = split( /;/, $ln );
next unless substr( $fields[1], 0, 1 ) == 6;
@fields = @fields[0,1,2];
push @out, join( ";", @fields );
}
corp.mail.ru
Бизнес логика
6. open my $out, ">", "/tmp/out.txt";
syswrite( $out, join( $/, @out );
close $out;
corp.mail.ru
Пишем в файл
7. • Задача решена
• Код простой работает быстро
• Аспекты разделены
• Проблема с размером файла
corp.mail.ru
Подумаем
8. open my $in, "/tmp/in.csv";
open my $out, ">", "/tmp/out.txt";
while ( my $ln = <$in> ) {
chomp $ln;
my @fields = split( /;/, $ln );
next unless
substr( $fields[1], 0, 1 ) == 6;
@fields = @fields[0,1,2];
syswrite( $out, join( ";", @fields )."n" );
}
close $out; close $in;
corp.mail.ru
Винегрет
9. • Проблема с размером решена
• Быстродействие не пострадало
• Аспекты перемешались
• Модифицировать все труднее
corp.mail.ru
Еще подумаем
10. • Задача и быстрое решение
• Немного теории
• Используем callbacks
• Еще немного теории
• Используем итераторы
• Заключение
11. my $double = sub {
my $val = shift;
return $val * 2;
};
$double->( 4 ); # 8
corp.mail.ru
Анонимная sub
12. • Динамическое создание
• Ограниченное время жизни
• Не видна снаружи
• Диспетчеризация
• Можно передавать в качестве параметра
• И это еще не все…
corp.mail.ru
Особенности
13. sub sub_factory {
my $multiplier = shift;
return sub {
return shift * $muliplier;
}
}
my $double = sub_factory( 2 );
my $triple = sub_factory( 3 );
$double->( 3 ); # 6
$triple->( 4 ); # 12
corp.mail.ru
Closure
14. sub do_action {
my ( $action, $value ) = @_;
return $action->( $value );
}
my $double = sub_factory( 2 );
my $triple = sub_factory( 3 );
do_action( $double, 12 ); # 24
do_action( $triple, 7 ); # 21
corp.mail.ru
Closure as param
15. sub create_summer {
my $sum = 0;
return sub {
return( $sum += shift );
}
}
my $s1 = create_summer();
my $s2 = create_summer();
$s1->( 1 ); # 1
$s2->( 2 ); # ?
$s1->( 3 ); #
$s2->( 4 ); #
corp.mail.ru
Closure data
16. sub create_summer {
my $sum = 0;
return sub {
return( $sum += shift );
}
}
my $s1 = create_summer();
my $s2 = create_summer();
$s1->( 1 ); # 1
$s2->( 2 ); # 2
$s1->( 3 ); # ?
$s2->( 4 ); #
corp.mail.ru
Closure data
17. sub create_summer {
my $sum = 0;
return sub {
return( $sum += shift );
}
}
my $s1 = create_summer();
my $s2 = create_summer();
$s1->( 1 ); # 1
$s2->( 2 ); # 2
$s1->( 3 ); # 4
$s2->( 4 ); # 6
corp.mail.ru
Closure data
18. • Персональная копия данных
• Доступ к данным только у closure
• Работа в контексте в котором была создана
• Передача closure в качестве параметров
corp.mail.ru
Closure итог
19. • Задача и быстрое решение
• Немного теории
• Используем callbacks
• Еще немного теории
• Используем итераторы
• Заключение
20. sub reader {
my ( $fn, $cb ) = @_;
open my $in, $fn;
while ( my $ln = <$in> ) {
chomp $ln;
$cb->( $ln );
}
close $in;
}
corp.mail.ru
Читаем файл
21. sub writefile {
my ( $fn, $cb ) = @_;
open my $out, ">","/tmp/out.csv";
$cb->( sub {
my $ln = shift;
syswrite( $out, $ln . $/ );
} );
close $out;
}
corp.mail.ru
Пишем файл
22. write_file( "/tmp/out.cvs", sub {
my $writer = shift;
reader( "/tmp/in.csv", sub {
my $ln = shift;
my @fields = split( /;/, $ln );
next unless
substr( $fields[1], 0, 1 )==6;
@fields = @fields[0,1,2];
$writer->( join( ";", @fields ) );
}); });
corp.mail.ru
Собираем вместе
23. • Разнесли логику
• Сберегли память
• Растет вложенность
• Запутанный управляющий код
• Контроль над процессом
corp.mail.ru
24. • Задача и быстрое решение
• Немного теории
• Используем callbacks
• Еще немного теории
• Используем итераторы
• Заключение
25. • Итератор, он же курсор
• Выполняет только одну функцию
• Отделяет обход от хранилища
• Можно передать куда угодно
corp.mail.ru
Итератор
26. my $ln = <STDIN>;
$ary_ref = $sth->fetchrow_arrayref;
while(my ($key,$value) = each %hash )
while ( /abc/g )
my $i = rand();
corp.mail.ru
Примеры
27. sub sorted {
my @array = sort @_;
sub {
shift @array;
}
}
my $s = sorted( qw/e d c b a/ );
while ( my $c = $a->() ) {
print "$cn";
}
corp.mail.ru
Не ленивый итератор
28. sub up_to {
my ( $from, $to ) = @_;
sub {
return if $from > $to;
return $from++;
}
}
my $a = up_to( 10, 20 );
while ( my $i = $a->() ) {
print "$in";
}
corp.mail.ru
Усложняем…
29. sub fib {
my ( $f0, $f1, $f2 ) = ( undef, 0, 1 );
sub {
( $f0,$f1,$f2 ) = ( $f1,$f2,$f1+$f2 );
return $f0;
}
}
my $f = fib();
for ( 1..100 ) {
printf "%sn", $f->();
}
corp.mail.ru
The must
30. • Задача и быстрое решение
• Немного теории
• Используем callbacks
• Еще немного теории
• Используем итераторы
• Заключение
32. sub reader {
my ( $fn ) = @_;
open my $in, $fn;
sub {
my $ln = <$in>;
chomp $ln;
return { line => $ln } if $ln;
close $fn;
return;
} }
corp.mail.ru
Генератор из файла
33. sub igrep(&@) {
my ( $cb, $it ) = @_;
sub {
while( my $val = $it->() ) {
return $val
if $cb->( $val );
}
return;
}
}
corp.mail.ru
Фильтруем
34. sub imap(&@) {
my ( $cb, $it ) = @_;
sub {
return
unless my $v = $it->();
return $cb->( $v );
}
}
corp.mail.ru
Преобразуем
35. sub ireduce(&@) {
my ( $cb, $it, $accum ) = @_;
while ( my $val = $it->() ) {
$accum = $cb->( $val,$accum )
}
return $accum;
}
corp.mail.ru
Схлопываем
36. sub write_file {
my ( $it, $fn ) = @_;
open my $out, ">", $fn;
my $byteCount = ireduce {
$_[1] + syswrite( $out,
$_[0]->{line} . $/ )
} $it;
close $out;
return $byteCount;
}
corp.mail.ru
Итератор в файл
38. • Разнесли аспекты
• Память не кушаем
• Управление по необходимости
• Сохраняем не данные а метод
corp.mail.ru
В итоге
39. sub { { ab => 1, b => 2 } }
sub { { 'a' . 'c' => 1, b => 2 } }
corp.mail.ru
Perl magic plus
40. sub { { ab => 1, b => 2 } }
sub { { 'a' . 'c' => 1, b => 2 } }
sub { +{ 'a'.'c' => 1, b => 2 }
sub { return { 'a'.'c'=>1, b => 2 } }
corp.mail.ru
Perl magic plus
41. • Задача и быстрое решение
• Немного теории
• Используем callbacks
• Еще немного теории
• Используем итераторы
• Заключение
42. • Разнородные данные
• Исследование, пробы
• Нестабильность формата
• Легкость модификации
corp.mail.ru
Практическая часть