dsls в perl
DESCRIPTION
Технология реализации DSL в Perl без использования Devel::Declare. О том как это работает и какие трюки Perl можно использовать.TRANSCRIPT
![Page 1: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/1.jpg)
DSLs в PerlDSLs в Perl
Как?Как?
Руслан Закиров <Руслан Закиров <[email protected]@bestpractical.com>>Best Practical Solutions, 2008Best Practical Solutions, 2008
![Page 2: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/2.jpg)
Что?Что?
![Page 3: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/3.jpg)
under 'user/*' => run {under 'user/*' => run { my $u = U->load($1);my $u = U->load($1); ......}}
![Page 4: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/4.jpg)
under 'user/*' => run {under 'user/*' => run { … … abort(404) unless $u;abort(404) unless $u; on 'profile' => run {};on 'profile' => run {}; on 'stats' => run {};on 'stats' => run {}; on 'blog' => run {};on 'blog' => run {};}}
![Page 5: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/5.jpg)
Зачем?Зачем?
![Page 6: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/6.jpg)
ВыразительноВыразительно
![Page 7: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/7.jpg)
УправляемоУправляемо
![Page 8: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/8.jpg)
Как?Как?
![Page 9: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/9.jpg)
ПрототипыПрототипы
![Page 10: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/10.jpg)
ПрототипыПрототипы
($)($)(&)(&)(@)(@)
![Page 11: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/11.jpg)
Прототипы (завтрак)Прототипы (завтрак)
sub set($$) {...}sub set($$) {...}set key => $val;set key => $val;
![Page 12: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/12.jpg)
Прототипы (запястья)Прототипы (запястья)
() ()
![Page 13: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/13.jpg)
ПрототипыПрототипы
(&)(&)блокблок
функцияфункция
![Page 14: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/14.jpg)
ПрототипыПрототипы
grep {} @_grep {} @_sub grep(&@) {}sub grep(&@) {}
![Page 15: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/15.jpg)
МетодыМетоды
![Page 16: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/16.jpg)
МетодыМетоды
$o = new X k => $v;$o = new X k => $v;
![Page 17: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/17.jpg)
МетодыМетоды
perl -e 'title is „foo”;'perl -e 'title is „foo”;'
![Page 18: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/18.jpg)
МетодыМетоды
Невозможно найти Невозможно найти метод "title" в пакете метод "title" в пакете
"is""is"
![Page 19: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/19.jpg)
МетодыМетоды
может может ввммы забыли ы забыли загрузить "is"?загрузить "is"?
![Page 20: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/20.jpg)
МетодыМетоды
этап исполненияэтап исполнения
![Page 21: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/21.jpg)
МетодыМетоды
perl -e 'sub foo { title perl -e 'sub foo { title is „foo” }'is „foo” }'нет ошибкинет ошибки
![Page 22: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/22.jpg)
МетодыМетоды
my $a = {};my $a = {};local *is::AUTOLOAD = sub {local *is::AUTOLOAD = sub { shift; # isshift; # is $a->{$AUTLOAD} = join ' ', @_$a->{$AUTLOAD} = join ' ', @_};};$call->(); # что-то$call->(); # что-то
![Page 23: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/23.jpg)
ОбъединимОбъединим
![Page 24: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/24.jpg)
Объеденим (img_simple.pl)Объеденим (img_simple.pl)
sub img(&) {sub img(&) { my $code = shift; my $code = shift; my %attr;my %attr; local *is::AUTOLOAD = sub {...};local *is::AUTOLOAD = sub {...}; $code->();$code->(); my $attrs = join ' ',my $attrs = join ' ', map $_.'=”'.$attr{$_},map $_.'=”'.$attr{$_}, keys %attr;keys %attr; print „<img $attrs />”;print „<img $attrs />”;}}
![Page 25: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/25.jpg)
Слишком просто?Слишком просто?
![Page 26: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/26.jpg)
Усложним (img_strict.pl)Усложним (img_strict.pl)my %attr_checks = (my %attr_checks = ( img => {img => { _mandatory => [qw(src alt)],_mandatory => [qw(src alt)], src => {src => { canonicalizer => sub {...},canonicalizer => sub {...}, provides => sub {...},provides => sub {...}, },}, # ...# ... },},););
![Page 27: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/27.jpg)
Усложним (img_strict.pl)Усложним (img_strict.pl)
canonicalizer => sub {canonicalizer => sub { return "/static/images/$_[0]"return "/static/images/$_[0]" unless $_[0] =~ /^\//;unless $_[0] =~ /^\//; return $_[0];return $_[0];}}
![Page 28: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/28.jpg)
Усложним (img_strict.pl)Усложним (img_strict.pl)
provides => sub {provides => sub { return unless my ($w, $h) = return unless my ($w, $h) = ($_[0] =~ /-(\d+)x(\d+)\./);($_[0] =~ /-(\d+)x(\d+)\./); return (width => $w, height => $h);return (width => $w, height => $h);}}
![Page 29: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/29.jpg)
Результат (img_strict.pl)Результат (img_strict.pl)
img {img { alt is 'feed',alt is 'feed', src is 'f-14x14.png'src is 'f-14x14.png'};};
![Page 30: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/30.jpg)
Результат (img_strict.pl)Результат (img_strict.pl)
<img<img width="14"width="14" height="14"height="14" alt="feed"alt="feed" src="/s/i/f-14x14.png"src="/s/i/f-14x14.png"/>/>
![Page 31: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/31.jpg)
ОтладкаОтладка
![Page 32: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/32.jpg)
Отладка (carp.pl)Отладка (carp.pl)
нет атрибута нет атрибута 'boo' у тега 'img' 'boo' у тега 'img' at carp.pl at carp.pl line 10line 10
![Page 33: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/33.jpg)
Отладка (carp.pl)Отладка (carp.pl)
local $Carp::CarpLevel = 1;local $Carp::CarpLevel = 1;Carp::croak(...);Carp::croak(...);
![Page 34: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/34.jpg)
Отладка (carp.pl)Отладка (carp.pl)
нет атрибута нет атрибута 'boo' у тега 'img' 'boo' у тега 'img' at carp.pl at carp.pl line 16line 16место вызоваместо вызова
![Page 35: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/35.jpg)
Отладка (carp.pl)Отладка (carp.pl)
main::main::__ANON____ANON__() () called at carp.pl line 13called at carp.pl line 13
![Page 36: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/36.jpg)
Отладка (carp.pl)Отладка (carp.pl)
sub img(&) {sub img(&) { local *__ANON__local *__ANON__ = "img_impl";= "img_impl";......}}
![Page 37: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/37.jpg)
Отладка (carp.pl)Отладка (carp.pl)
bla-bla at carp.pl bla-bla at carp.pl line 17line 17main::main::img_implimg_impl() called at...() called at...main::img('CODE(...)') called at...main::img('CODE(...)') called at...
![Page 38: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/38.jpg)
Грабли №1Грабли №1
![Page 39: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/39.jpg)
Грабли №1Грабли №1
page {...};page {...};sub page(&) {...};sub page(&) {...};
![Page 40: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/40.jpg)
Грабли №1Грабли №1
Невозможно вызвать Невозможно вызвать метод "page" без метод "page" без пакета или объектапакета или объекта
![Page 41: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/41.jpg)
Грабли №2Грабли №2
![Page 42: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/42.jpg)
Грабли №2Грабли №2
sub page(&) {sub page(&) { local *title::page = sub {}local *title::page = sub {} shift->();shift->();};};pagepage { { pagepage title „qwe” }; title „qwe” };
![Page 43: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/43.jpg)
Грабли №2Грабли №2
Методы Методы проигрывают проигрывают протипампротипам
![Page 44: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/44.jpg)
Избавляемся от Избавляемся от методовметодов
![Page 45: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/45.jpg)
Без методов (wo_methods.pl)Без методов (wo_methods.pl)our %ATTR;our %ATTR;sub attrs(&) {sub attrs(&) { %ATTR = shift->()%ATTR = shift->()}}sub img(&) {sub img(&) { local %ATTR;local %ATTR; $code->();$code->(); ......}}
![Page 46: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/46.jpg)
Без методов (wo_methods.pl)Без методов (wo_methods.pl)
img { attrs {img { attrs { alt => 'boo', src => 'href' alt => 'boo', src => 'href' } };} };
![Page 47: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/47.jpg)
Вложенные Вложенные структурыструктуры
![Page 48: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/48.jpg)
Вложения (div_simple.pl)Вложения (div_simple.pl)
<div><div><div><div>что-точто-то
</div></div></div></div>
![Page 49: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/49.jpg)
Вложения (div_simple.pl)Вложения (div_simple.pl)
sub div(&) {sub div(&) { my $code = shift;my $code = shift; my $inside = $code->();my $inside = $code->(); return "<div>$inside</div>";return "<div>$inside</div>";}}print div { div {'some'} };print div { div {'some'} };
![Page 50: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/50.jpg)
Если что-то Если что-то сложнее?сложнее?
![Page 51: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/51.jpg)
УсложняемУсложняем
div {div { div {1};div{2}div {1};div{2}};};
![Page 52: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/52.jpg)
УсложняемУсложняем
<div><div><div>2</div><div>2</div></div></div>
![Page 53: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/53.jpg)
УсложняемУсложняем
Фигня вышлаФигня вышла
![Page 54: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/54.jpg)
Простое решениеПростое решение
![Page 55: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/55.jpg)
Простое решение (div_sol1.pl)Простое решение (div_sol1.pl)
sub div(&) {sub div(&) { my $code = shift;my $code = shift; my @inside = $code->();my @inside = $code->(); return "<div>@inside</div>";return "<div>@inside</div>";}}
![Page 56: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/56.jpg)
Простое решение (div_sol1.pl)Простое решение (div_sol1.pl)
print div { div {1}, div {2} },print div { div {1}, div {2} }, div { div {3}, div {4} };div { div {3}, div {4} };
![Page 57: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/57.jpg)
Код не вставишьКод не вставишь:(:(
![Page 58: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/58.jpg)
явный print явный print отстойотстой
![Page 59: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/59.jpg)
запятые в топкузапятые в топку
![Page 60: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/60.jpg)
Да прибудут с Да прибудут с вами контекстывами контексты
![Page 61: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/61.jpg)
Контексты (context1.pl)Контексты (context1.pl)
unless ( defined wantarray ) {unless ( defined wantarray ) { # void# void} elsif ( wantarray ) {} elsif ( wantarray ) { # array# array} else {} else { # scalar# scalar}}
![Page 62: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/62.jpg)
КонтекстыКонтексты
sub div(&) {sub div(&) { my $res = join '', shift->();my $res = join '', shift->(); unless ( defined wantarray ) {unless ( defined wantarray ) { print „<div>$res</div>”;print „<div>$res</div>”; } else {} else { return „<div>$res</div>”;return „<div>$res</div>”; }}}}
![Page 63: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/63.jpg)
Контексты (context1.pl)Контексты (context1.pl)
div { div {1}; div {2} };div { div {1}; div {2} };
<div>1</div><div>1</div><div><div>2</div></div><div><div>2</div></div>
![Page 64: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/64.jpg)
БуферизацияБуферизация
![Page 65: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/65.jpg)
Бу-эфиры (buffers1.pl)Бу-эфиры (buffers1.pl)
sub buffered {sub buffered { my $buf = '';my $buf = ''; local *STDOUT;local *STDOUT; open STDOUT, '>', \$buf;open STDOUT, '>', \$buf; return $buf . join('', shift->());return $buf . join('', shift->());}}
![Page 66: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/66.jpg)
Бу-эфиры (buffers1.pl)Бу-эфиры (buffers1.pl)
sub div(&) {sub div(&) { my $res = buffered(shift); my $res = buffered(shift); return „<div>$res</div>”return „<div>$res</div>” if defined wantarray;if defined wantarray; print „<div>$res</div>”;print „<div>$res</div>”;}}
![Page 67: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/67.jpg)
Бу-эфиры (buffers1.pl)Бу-эфиры (buffers1.pl)
div {div { div{'menu'};div{'menu'}; my $some = 'some';my $some = 'some'; div{$some},div{$some}, div{'tail'}div{'tail'}};};
![Page 68: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/68.jpg)
ЯХУ! :)ЯХУ! :)
![Page 69: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/69.jpg)
Грабли №3Грабли №3
![Page 70: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/70.jpg)
Грабли №3Грабли №3
div {div { 'some';'some'; my $some = 'some';my $some = 'some'; div{$some}div{$some}};};
![Page 71: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/71.jpg)
Грабли №3Грабли №3
print 'some';print 'some';outs('some');outs('some');x {'some'}x {'some'}{ my $x=...; 'some', div{$x} }{ my $x=...; 'some', div{$x} }
![Page 72: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/72.jpg)
Установка Установка функцийфункций
![Page 73: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/73.jpg)
Установка функцийУстановка функций
my @tags = qw(a b);my @tags = qw(a b);foreach my $t ( @tags ) {foreach my $t ( @tags ) { no strict 'refs';no strict 'refs'; *{'main::'.$t} = sub (&) {*{'main::'.$t} = sub (&) { ...... };};}}
![Page 74: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/74.jpg)
Установка функцийУстановка функций
sub import;sub import;Exporter;Exporter;Symbol;Symbol;И прочиеИ прочие
![Page 75: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/75.jpg)
Прото-цепочкиПрото-цепочки
![Page 76: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/76.jpg)
Это не химияЭто не химияИ не биологияИ не биология
![Page 77: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/77.jpg)
ЭтоЭто(&;$)(&;$)
![Page 78: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/78.jpg)
Прото-цепочкиПрото-цепочки
sub a(&;$) {sub a(&;$) { print 'a ', context wantarray, "\n"print 'a ', context wantarray, "\n"}}sub b(&;$) {sub b(&;$) { print 'b ', context wantarray, "\n"print 'b ', context wantarray, "\n"}}
![Page 79: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/79.jpg)
Прото-цепочкиПрото-цепочки
a {} b {};a {} b {};
bb scalar scalara voida void
![Page 80: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/80.jpg)
Промежуточное Промежуточное прдставлениепрдставление
![Page 81: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/81.jpg)
Пром-представленияПром-представления*{'main::'.$t} = sub (&;$) {*{'main::'.$t} = sub (&;$) { my ($code, $next) = @_;my ($code, $next) = @_; unless ( defined wantarray ) {unless ( defined wantarray ) { return _tag($t, $code, $next);return _tag($t, $code, $next); } else {} else { return return bless subbless sub { { return _tag($t, $code, $next)return _tag($t, $code, $next) }, 'MyTag';}, 'MyTag'; }}};};
![Page 82: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/82.jpg)
Пром-представленияПром-представления
package MyTag;package MyTag;use overload '""' => sub {use overload '""' => sub { return buffered($_[0])return buffered($_[0])};};1;1;
![Page 83: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/83.jpg)
Пром-представленияПром-представления
a {'head'}a {'head'} b {'middle'}b {'middle'}
c {'tail'};c {'tail'};im_represent.plim_represent.pl
![Page 84: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/84.jpg)
ЭкранированиеЭкранирование
![Page 85: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/85.jpg)
ЭкранированиеЭкранирование
sub _escape {sub _escape { return unless defined $_[0];return unless defined $_[0]; my $v = shift;my $v = shift; $v = „$v”$v = „$v”;; $v =~ s/.../.../g;$v =~ s/.../.../g; return $v;return $v;}}
![Page 86: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/86.jpg)
ЭкранированиеЭкранирование
sub escape(@_) {sub escape(@_) { return mapreturn map blessed($_)blessed($_) && $_->isa('MyTag')&& $_->isa('MyTag') ? $_ : _escape($_),? $_ : _escape($_), @_;@_;}}
![Page 87: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/87.jpg)
ЭкранированиеЭкранированиеsub buffered {sub buffered { ...... return join '', $buf, return join '', $buf, escape(@tail);escape(@tail);}}sub _tag {sub _tag { my ($tag, $code, $next) = @_;my ($tag, $code, $next) = @_; ...... print join '', $res, escape $next;print join '', $res, escape $next;}}
![Page 88: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/88.jpg)
Все работаетВсе работаетescaping.plescaping.pl
![Page 89: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/89.jpg)
На закуску к экранамНа закуску к экранам
sub outs(@) { print _escape(join '', @_) }sub outs(@) { print _escape(join '', @_) }
sub raw(@) { print join '', @_ }sub raw(@) { print join '', @_ }
# грабли №3# грабли №3div { div { outs('some');outs('some'); div {...} }; div {...} };
![Page 90: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/90.jpg)
MyTD готов.MyTD готов.Осталось Осталось только...только...
![Page 91: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/91.jpg)
Недостающие частиНедостающие части
объединить все примерыобъединить все примерызапаковать всезапаковать все
sub template($$);sub template($$);# template 'index' => run {};# template 'index' => run {};sub show($@);sub show($@);# show 'index', arg => $arg, ...;# show 'index', arg => $arg, ...;
![Page 92: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/92.jpg)
ПосмотретьПосмотреть
Template::DeclareTemplate::DeclareJifty::DispatcherJifty::DispatcherJifty::Param::SchemaJifty::Param::SchemaJifty::DBI::SchemaJifty::DBI::SchemaObject::DeclareObject::DeclareB::*B::*
![Page 93: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/93.jpg)
ВСЕВСЕ
![Page 94: DSLs в Perl](https://reader037.vdocuments.net/reader037/viewer/2022102902/55878e13d8b42a485d8b4619/html5/thumbnails/94.jpg)
Вопросы?Вопросы?