Видео: http://video.mail.ru/corp/p.scherbinin/6/7.html
Tаблица символов — это только небольшой шаг в мир внутреннего устройства Perl, но и он открывает программисту огромные возможности:
— Runtime-кодогенерация.
— Генерация по запросу.
— Изменение кода сторонних модулей на лету и многое другое.
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Moscow.pm
Видео: http://video.mail.ru/corp/p.scherbinin/6/11.html
— Знай свою среду. Почему нужно изучать язык, на котором пишешь.
— Магии нет. Есть непонимание процессов.
— Не верь предрассудкам. Они сложились при других обстоятельствах.
— Доверяй, но проверяй. Прежде, чем использовать решение, проверь.
— Не используй не изучив. Не используй не понимая.
— Код можно менять. Как делать это с умом.
— Можно ли доверять синтетике? Синтетические тесты и реальная нагрузка.
— Немного примеров. Плохих и хороших.
Пластилиновый код: как перестать кодить и начать житьMoscow.pm
Елена Шишкина, ведущий программист Деньги Mail.Ru. Она покажет практический пример лени как двигателя прогресса в отдельно взятом веб-проекте:
- Надоело писать код? Будем думать, как его не писать!
- Боремся с однотипным кодом. Боремся с неоднотипным кодом.
- Код, которого не существует, и код, который существует.
- Следите за руками: программируем на конфигах!
- Как жить дальше?
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Moscow.pm
Видео: http://video.mail.ru/corp/p.scherbinin/6/11.html
— Знай свою среду. Почему нужно изучать язык, на котором пишешь.
— Магии нет. Есть непонимание процессов.
— Не верь предрассудкам. Они сложились при других обстоятельствах.
— Доверяй, но проверяй. Прежде, чем использовать решение, проверь.
— Не используй не изучив. Не используй не понимая.
— Код можно менять. Как делать это с умом.
— Можно ли доверять синтетике? Синтетические тесты и реальная нагрузка.
— Немного примеров. Плохих и хороших.
Пластилиновый код: как перестать кодить и начать житьMoscow.pm
Елена Шишкина, ведущий программист Деньги Mail.Ru. Она покажет практический пример лени как двигателя прогресса в отдельно взятом веб-проекте:
- Надоело писать код? Будем думать, как его не писать!
- Боремся с однотипным кодом. Боремся с неоднотипным кодом.
- Код, которого не существует, и код, который существует.
- Следите за руками: программируем на конфигах!
- Как жить дальше?
Anton Shabouta "Implementing async binary clients in pure PHP" Fwdays
- Have you ever think how PDO work under the hood?
- What if tomorrow you need to write own DB driver from scratch?
- How to approach such tasks and get around the pitfalls?
- Is it possible to achieve in pure PHP performance comparable to the C extension?
In this talk I will try to answer these and other questions related to the development of clients for various binary protocols. We also analyze the nuances of the asynchronous driver implementation and dive into the world of low-level and not-so-optimizations.
Доклад с WordCamp Moscow 2017 посвящен распространенным ошибкам у разработчиков плагинов и тем в WordPress. Советы и рекомендации, как можно сделать свой продукт лучше и удобнее для пользователей и разработчиков.
Anton Shabouta "Implementing async binary clients in pure PHP" Fwdays
- Have you ever think how PDO work under the hood?
- What if tomorrow you need to write own DB driver from scratch?
- How to approach such tasks and get around the pitfalls?
- Is it possible to achieve in pure PHP performance comparable to the C extension?
In this talk I will try to answer these and other questions related to the development of clients for various binary protocols. We also analyze the nuances of the asynchronous driver implementation and dive into the world of low-level and not-so-optimizations.
Доклад с WordCamp Moscow 2017 посвящен распространенным ошибкам у разработчиков плагинов и тем в WordPress. Советы и рекомендации, как можно сделать свой продукт лучше и удобнее для пользователей и разработчиков.
Дмитрий Щадей "Зачем и как мы используем jsLint"Yandex
Все знают, что «JSLint – статический анализатор кода», но никто не спешит его использовать в собственных проектах. В докладе рассказывается о том, каким образом и какой ценой он упростит вам жизнь. И разумеется, поставлен вопрос «почему» перед каждой jslint-овой ошибкой, а также рассматривается, как можно интегрировать JSLint в ваш проект.
Доклад о разработке (а главное - оптимизации) программы на Perl под Raspberry PI.
Наглядно показывает, что в Perl есть немало возможностей, а также инструментов, которые позволяют делать программы быстрее и эффективнее - используя как преимущества самого языка, так и оптимизацию алгоритма программы.
Наталья Савенкова, ex-СТО SHOP2YOU.RU. В e-commerce файлы формата Excel – основной инструмент обмена данными. Они используются везде: для документов покупателям и транспортным компаниям, для отчетов менеджерам, для импорта и экспорта товаров в магазин, для обмена остатками между поставщиками. Их нужно уметь читать и писать. Наталья объяснит, как это делать с документами разной структуры, а также поговорит о сложностях и их решениях. Доклад посвящен классическому формату Excel 1997-2003 (XLS) и модулям: Spreadsheet::ParseExcel, Spreadsheet::WriteExcel и Excel::Template.
Fast queue – как мы сделали свою очередь на perl и redisMoscow.pm
Иван Соколов, teamlead REG.RU. Очередь – один из наиболее используемых механизмов в программировании. Например, для интеграции с платежными системами или для обработки медиа-контента, загруженного пользователем, необходимо наличие очередей.
В REG.RU тоже не обходятся без очередей. Поэтому потребность найти решение появилась достаточно давно. Учитывая специфику компании как доменного регистратора большинство существующих решений не подходило, и программисты решили «написать свой велосипед». Иван расскажет об архитектуре их очереди, ее возможностях, и в каких задачах она используется.
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013Moscow.pm
- Как создать презентацию не вылезая из любимого текстового редактора (notepad++, padre, vim).
- Как perl помогает автоматизировать работу без написания кода.
- Пара скриптов, которые облегчают работу на разных платформах.
- Те же скрипты на perl6.
- Автоматизация и тестирование Firefox.
Особенности создания XS-модулей на языке C++. Владимир Тимофеев. Moscow.pm 4 ...Moscow.pm
- Почему C++? Плюсы, минусы.
- Как найти компилятор (поддержка в EUMM, MB, стандартные и не очень решения).
- Конфликты имён.
- Трансляция C++ исключений в Perl-исключения.
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Moscow.pm
— От циклов к коллбэкам
— От коллбэков к итераторам
— Борьба со сложностью, изоляция аспектов
— Гибкость и модифицируемость кода
— Преимущества и недостатки
Преобразование Perl-структур в XML. Трефилова Екатерина. Moscow.pm 6 июля 2013Moscow.pm
— Парсинг XML-документов.
— Формирование простых и сложных XML
— Немного о DOM и парсерах, основанных на событиях SAX
— Какими модулями удобно пользоваться и почему
Play Perl — распределенная социальная игра для Perl-разработчиков. Вячеслав М...Moscow.pm
Видео: http://video.mail.ru/corp/p.scherbinin/6/10.html
Расскал о том:
— Как настоящие соцсети будущего будут поощрять действие, а не потребление.
— Как геймификация изменит мир.
— Как Play Perl спасет сообщество perl-разработчиков от застоя и сделает нас всех более продуктивными.
2. • Какие-то проблемы?
• Методы runtime-
кодогенерации
• Таблица символов:
матчасть
• От теории к практике
• Как не выстрелить себе
в ногу
• RTFM
2
3. • Конструкторы
• Методы-аксессоры
• Идентичная предварительная обработка
данных
• Похожие по функционалу функции с
небольшими отличиями
corp.mail.ru
Повторяющийся код
4. package Foo;
sub new {
return bless {}, shift;
}
package Bar;
sub new {
return bless {}, shift;
}
www.mail.ru 4
Конструкторы
5. sub field1 {
my $self = shift;
$self->{field1} = $_[0] if @_;
return $self->{field1};
}
sub field2 {
my $self = shift;
$self->{field2} = $_[0] if @_;
return $self->{field2};
}
sub field3 {
my $self = shift;
$self->{field3} = $_[0] if @_;
return $self->{field3};
}
www.mail.ru 5
Аксессоры
6. sub do_something {
my $self = shift;
$self->check_cookies;
return $self->redirect('/login') unless $self->check_auth;
my $form = $self->load_form('do_something');
$form->fetch;
return $self->render_error() unless $form->validate;
my $some_user_data = $self->load_user_data;
...
}
sub do_another_thing {
my $self = shift;
$self->check_cookies;
...
}
www.mail.ru 6
Предварительная
обработка
7. sub error {
my $message = shift;
my ($package, $line, $sub) = (caller(0))[0, 2, 3];
print $log scalar localtime, "ERROR: ${package}::$sub ($line): $messagen";
print $log Carp::longmess if $Trace_Errors;
}
sub debug {
my $message = shift;
my ($package, $line, $sub) = (caller(0))[0, 2, 3];
print $log scalar localtime, "DEBUG: ${package}::$sub ($line): $messagen";
}
sub info { ... }
sub warning { ... }
www.mail.ru 7
Похожие функции
8. • Потеря времени на
перепечатывание/копирование
• Ошибки из-за невнимательности
• Трудоемкость сопровождения
corp.mail.ru
Проблемы повторяющегося кода
9. • Ошибки в реализации
• Отсутствие поддержки кириллицы
• Недостаточный функционал
corp.mail.ru
Сторонние модули
10. print Dumper {test => 'Тестовая строка'};
www.mail.ru 10
Data::Dumper и
кириллица в utf8
$VAR1 = {
"test" =>
"x{422}x{435}x{441}x{442}x{43e}x{432}x{430}x
{44f} x{441}x{442}x{440}x{43e}x{43a}x{430}"
};
11. package Foo;
use Moose;
has field1 => (is => 'rw');
has field2 => (is => 'rw');
has field3 => (is => 'rw');
around [qw(do_something do_another_thing)] => sub {
my ($orig, $self) = @_;
...
$self->$orig(form => $form, user_data => $some_user_data);
};
www.mail.ru 11
Решение: CPAN
12. • Необходимость доказательства
целесообразности
• Замусоривание системы
• Замусоривание блоков use в коде
• Снижение производительности
• Увеличение времени компиляции
• Расход памяти
• Уменьшение контроля над кодом («чужой
код»)
www.mail.ru 12
Проблемы использования
сторонних модулей
13. • Какие-то проблемы?
• Методы runtime-
кодогенерации
• Таблица символов:
матчасть
• От теории к практике
• Как не выстрелить себе
в ногу
• RTFM
13
15. use Data::Dumper;
$Data::Dumper::Useqq = 1;
{
no warnings 'redefine';
package Data::Dumper;
sub Data::Dumper::qquote {
my $s = shift;
return "'$s'";
}
}
www.mail.ru 15
Переопределение
16. package Wrapper;
sub make_accessors {
my $package = caller(0);
for (@_) {
eval qq{
package $package;
sub $_ {
my $self = shift;
$self->{$_} = $_[0] if @_;
return $self->{$_};
}
};
}
}
www.mail.ru 16
eval
17. package Test;
use Wrapper;
sub new { return bless {}, shift; }
Wrapper::make_accessors( qw(name age) );
package main;
use Test;
my $obj = Test->new;
$obj->name('Ann');
say $obj->name;
www.mail.ru 17
eval
18. • Какие-то проблемы?
• Методы runtime-
кодогенерации
• Таблица символов:
матчасть
• От теории к практике
• Как не выстрелить себе
в ногу
• RTFM
18
19. • Таблица символов – это хэш
www.mail.ru 19
Таблица символов
• Ключи – глобальные переменные и
подпрограммы
• Значения - тайпглобы
%PackageName::
%main::
20. www.mail.ru 20
Таблица символов
package Test;
our $data = 'test';
our @data = qw(1 2 3);
our %data = (key1 => 'value1', key2 =>
'value2');
sub data { return 0; }
package main;
say $Test::{$_} for keys %Test::;
*Test::data
my $fh = *FH;
21. *glob{PACKAGE} имя пакета
*glob{NAME} имя элемента (переменной или функции)
*glob{SCALAR} ссылка на значение-скаляр
*glob{ARRAY} ссылка на значение-массив
*glob{HASH} ссылка на значение-хэш
*glob{CODE} ссылка на подпрограмму
corp.mail.ru
Структура тайпглоба
22. Получение данных
my $scalar = ${ *Test::data };
my %hash = %{ *Test::data };
my @array = @{ *Test::data };
&{ *Test::data }();
Запись данных
*Test::data = 'new value';
*Test::data = [4, 5, 6];
*Test::data = {
key3 => 'value3',
key4 => 'value4‘
};
*Test::data = sub { return 1; };
www.mail.ru 22
Работа с тайпглобом
23. • Какие-то проблемы?
• Методы runtime-
кодогенерации
• Таблица символов:
матчасть
• От теории к практике
• Как не выстрелить себе
в ногу
• RTFM
23
24. package MakeAccessor;
sub import {
my $package = caller(0);
no strict 'refs';
*{"$package::has"} = &has;
}
sub has ($) {
my $name = shift;
my $package = caller(0);
no strict 'refs';
*{"$package::$name"} = sub {
my $self = shift;
$self->{$name} = $_[0] if @_;
return $self->{$name};
};
}
www.mail.ru 24
Генерация аксессоров
package Test;
use MakeAccessor;
has 'name';
has 'age';
sub new { return bless
{}, shift; }
package main;
my $o = Test->new;
$o->name('Ann');
say $o->name;
25. package MakeAccessor;
sub import {
my $package = caller(0);
no strict 'refs';
*{"$package::has"} = &has;
}
sub has ($) {
my $name = shift;
my $package = caller(0);
no strict 'refs';
*{"$package::$name"} = sub {
my $self = shift;
say ((caller(0))[3]);
$self->{$name} = $_[0] if @_;
return $self->{$name};
};
}
www.mail.ru 25
Боремся с __ANON__
MakeAccessor::__ANON__
26. www.mail.ru 26
Боремся с __ANON__
package MakeAccessor;
sub import {
my $package = caller(0);
no strict 'refs';
*{"$package::has"} = &has;
}
sub has ($) {
my $name = shift;
my $package = caller(0);
my $method = sub {
local *__ANON__ = "$package::$name";
my $self = shift;
$self->{$name} = $_[0] if @_;
return $self->{$name};
};
no strict 'refs';
*{"$package::$name"} = $method;
}
Test::name
27. • Генераторы классов: десериализация, ORM
• Реализация паттерна «прокси»
• Тестирование: mock, stub, fake object
• Хуки для подпрограмм: before, after, around
• Патчи во время выполнения
• Расширение функционала сторонних модулей
• Синонимы для устаревших функций при
рефакторинге
www.mail.ru 27
От теории к практике
28. package Response;
use CGI;
sub new {
return bless { cgi => CGI->new }, shift;
}
our $AUTOLOAD;
sub AUTOLOAD {
my ($method) = $AUTOLOAD =~ /([^:]+)$/;
return if $method eq 'DESTROY';
return unless CGI->can($method);
my $sub = sub {
local *__ANON__ = $AUTOLOAD;
my $self = shift;
return $self->{cgi}->$method(@_);
};
{ no strict 'refs';
*{$AUTOLOAD} = $sub;
};
return $sub->(@_);
}
www.mail.ru 28
Прокси
package main;
my $obj = Response->new;
print $obj->header('text/html');
Content-Type:text/html;
charset=ISO-8859-1
29. package Wrapper;
sub make_deprecated {
my $deprecated = shift;
{
no strict 'refs';
return if *{$deprecated}{CODE};
};
my $package = scalar caller(0);
my $method = (caller(1))[3];
my $func = sub {
local *__ANON__ = $deprecated;
warn "$deprecated called at " . sprintf("%s
(%s)", (caller)[1, 2]) . " is deprecated. Use
$package::$methodn";
eval "use $package;" unless $package->can('can');
my $sub = $package->can($method);
$sub->(@_);
};
no strict 'refs';
*{$deprecated} = $func;
}
package Test1;
package Test2;
sub new_func {
Wrapper::make_deprecated(
'Test1::old_func');
return 'test';
}
package main;
say Test2::new_func();
say Test1::old_func();
www.mail.ru 29
Синонимы
test
Test1::old_func called at test12.pl
(40) is deprecated. Use
Test2::Test2::new_func
test
30. use Test::More;
my $user_data = { ... };
{
no strict 'refs';
*{'Cache::Memcached::set'} = sub {
return 1;
};
*{'Cache::Memcached::get'} = sub {
return to_json($user_data);
};
};
is_deeply($user->get_info($session_id), $user_data, 'Some test...');
www.mail.ru 30
Stub
31. package Wrapper;
sub before(@&) {
my ($methods, $wrapper) = @_;
my $package = caller(0);
for my $method (@$methods) {
my $orig = $package->can($method);
my $sub = sub {
local *__ANON__ =
"$package::$method";
$wrapper->(@_);
$orig->(@_);
};
no strict 'refs';
*{"$package::$method"} = $sub;
}
}
package Test;
sub test { say 'test'; }
Wrapper::before [ 'test' ], sub { say 'wrapper';
};
package main;
Test::test();
www.mail.ru 31
Хуки
wrapper
test
32. • Какие-то проблемы?
• Методы runtime-
кодогенерации
• Таблица символов:
матчасть
• От теории к практике
• Как не выстрелить себе
в ногу
• RTFM
32
33. • Прагмы strict и warnings
• __ANON__ в трассировке стэка
• Ссылки на переопределяемые функции
• Снижение читабельности кода и повышение
требований к профессиональному уровню
программистов
• Рост стэка при использовании хуков
• Пространство имен модуля
www.mail.ru 33
Проблемы
кодогенерации
34. use Data::Dumper;
*{Data::Dumper::Dumper} = sub {
return 'Hacked!';
};
say Dumper({key1 => 1, key2 => 2});
say Data::Dumper::Dumper({key1 => 1, key2 => 2});
www.mail.ru 34
Ссылки
35. package Wrapper;
our $name = 'Ann';
*{Test::test} = sub {
say $name;
say $Test::name;
};
package Test;
our $name = 'Bob';
package main;
Test::test();
www.mail.ru 35
Пространство имен
36. eval
• Компиляция во время
выполнения
• Ускоренная
загрузка, возможность
компиляции по запросу
• Создание символов в
пространстве имен нужного
модуля
• Неэффективная генерация
большого количества
похожих функций
Таблица символов
• Компиляция при загрузке
• Проверка синтаксиса
компилятором при запуске
• Высокая эффективность
повторного использования
генераторов
• Невозможность создания
символов в пространстве
имен нужного модуля, если
имя последнего не известно
во время компиляции
www.mail.ru 36
37. • perlmod: Symbol tables
• perlref
• perldata: Typeglobs and
Filehandlers
• Sriram Srinivasan.Advanced
Perl Programming
• Modern Perl
(http://modernperlbooks.com)
www.mail.ru 37
Что почитать