SlideShare a Scribd company logo
1 of 94
Download to read offline
DSLs в Perl




    Как?

Руслан Закиров <ruz@bestpractical.com>
               <ruz@bestpractical.com>
           Best Practical Solutions, 2008
Что?
under 'user/*' => run {
  my $u = U->load($1);
  ...
}
under 'user/*' => run {
  …
  abort(404) unless $u;
  on 'profile' => run {};
  on 'stats' => run {};
  on 'blog' => run {};
}
Зачем?
Выразительно
Управляемо
Как?
Прототипы
Прототипы



 ($)
 (&)
 (@)
Прототипы (завтрак)




sub set($$) {...}
set key => $val;
Прототипы (запястья)




        ()
Прототипы



  (&)
 блок
функция
Прототипы




  grep {} @_
sub grep(&@) {}
Методы
Методы




$o = new X k => $v;
Методы




perl -e 'title is „foo”;'
Методы



 Невозможно найти
метод quot;titlequot; в пакете
         quot;isquot;
Методы




может вмы забыли
 загрузить quot;isquot;?
Методы




этап исполнения
Методы



perl -e 'sub foo { title
       is „foo” }'
      нет ошибки
Методы


my $a = {};
local *is::AUTOLOAD = sub {
  shift; # is
  $a->{$AUTLOAD} = join ' ', @_
};
$call->(); # что-то
Объединим
Объеденим (img_simple.pl)
sub img(&) {
  my $code = shift;
  my %attr;
  local *is::AUTOLOAD = sub {...};
  $code->();
  my $attrs = join ' ',
    map $_.'=”'.$attr{$_},
    keys %attr;
  print „<img $attrs />”;
}
Слишком просто?
Усложним (img_strict.pl)
my %attr_checks = (
   img => {
      _mandatory => [qw(src alt)],
      src => {
         canonicalizer => sub {...},
         provides => sub {...},
      },
      # ...
   },
);
Усложним (img_strict.pl)


canonicalizer => sub {
  return quot;/static/images/$_[0]quot;
   unless $_[0] =~ /^//;
  return $_[0];
}
Усложним (img_strict.pl)


provides => sub {
   return unless my ($w, $h) =
    ($_[0] =~ /-(d+)x(d+)./);
   return (width => $w, height => $h);
}
Результат (img_strict.pl)


img {
 alt is 'feed',
 src is 'f-14x14.png'
};
Результат (img_strict.pl)
<img
 width=quot;14quot;
 height=quot;14quot;
 alt=quot;feedquot;
 src=quot;/s/i/f-14x14.pngquot;
/>
Отладка
Отладка (carp.pl)


  нет атрибута
'boo' у тега 'img'
at carp.pl line 10
Отладка (carp.pl)




local $Carp::CarpLevel = 1;
Carp::croak(...);
Отладка (carp.pl)

  нет атрибута
'boo' у тега 'img'
at carp.pl line 16
  место вызова
Отладка (carp.pl)




  main::__ANON__()
  main::__ANON__()
called at carp.pl line 13
Отладка (carp.pl)

sub img(&) {
  local *__ANON__
    = quot;img_implquot;;
...
}
Отладка (carp.pl)



bla-bla at carp.pl line 17
main::img_impl() called at...
main::img_impl()
main::img('CODE(...)') called at...
Грабли №1
Грабли №1




page {...};
sub page(&) {...};
Грабли №1



Невозможно вызвать
 метод quot;pagequot; без
пакета или объекта
Грабли №2
Грабли №2


sub page(&) {
  local *title::page = sub {}
  shift->();
};
page { page title „qwe” };
Грабли №2


   Методы
проигрывают
  протипам
Избавляемся от
   методов
Без методов (wo_methods.pl)
our %ATTR;
sub attrs(&) {
  %ATTR = shift->()
}
sub img(&) {
  local %ATTR;
  $code->();
  ...
}
Без методов (wo_methods.pl)



img { attrs {
 alt => 'boo', src => 'href'
} };
Вложенные
структуры
Вложения (div_simple.pl)


 <div><div>
   что-то
</div></div>
Вложения (div_simple.pl)

sub div(&) {
   my $code = shift;
   my $inside = $code->();
   return quot;<div>$inside</div>quot;;
}
print div { div {'some'} };
Если что-то
 сложнее?
Усложняем


div {
 div {1};div{2}
};
Усложняем


<div>
<div>2</div>
</div>
Усложняем




Фигня вышла
Простое решение
Простое решение (div_sol1.pl)


sub div(&) {
  my $code = shift;
  my @inside = $code->();
  return quot;<div>@inside</div>quot;;
}
Простое решение (div_sol1.pl)




print div { div {1}, div {2} },
      div { div {3}, div {4} };
Код не вставишь
       :(
явный print
  отстой
запятые в топку
Да прибудут с
вами контексты
Контексты (context1.pl)


unless ( defined wantarray ) {
      # void
} elsif ( wantarray ) {
      # array
} else {
      # scalar
}
Контексты
sub div(&) {
  my $res = join '', shift->();
  unless ( defined wantarray ) {
     print „<div>$res</div>”;
  } else {
     return „<div>$res</div>”;
  }
}
Контексты (context1.pl)



div { div {1}; div {2} };

<div>1</div>
<div><div>2</div></div>
Буферизация
Бу-эфиры (buffers1.pl)

sub buffered {
  my $buf = '';
  local *STDOUT;
  open STDOUT, '>', $buf;
  return $buf . join('', shift->());
}
Бу-эфиры (buffers1.pl)

sub div(&) {
 my $res = buffered(shift);
 return „<div>$res</div>”
  if defined wantarray;
 print „<div>$res</div>”;
}
Бу-эфиры (buffers1.pl)

div {
 div{'menu'};
 my $some = 'some';
 div{$some},
 div{'tail'}
};
ЯХУ! :)
Грабли №3
Грабли №3


div {
 'some';
 my $some = 'some';
 div{$some}
};
Грабли №3



print 'some';
outs('some');
x {'some'}
{ my $x=...; 'some', div{$x} }
Установка
 функций
Установка функций

my @tags = qw(a b);
foreach my $t ( @tags ) {
   no strict 'refs';
   *{'main::'.$t} = sub (&) {
     ...
   };
}
Установка функций

sub import;
 Exporter;
  Symbol;
 И прочие
Прото-цепочки
Это не химия
И не биология
Это
(&;$)
Прото-цепочки


sub a(&;$) {
  print 'a ', context wantarray, quot;nquot;
}
sub b(&;$) {
  print 'b ', context wantarray, quot;nquot;
}
Прото-цепочки

a {} b {};

 b scalar
  a void
Промежуточное
 прдставление
Пром-представления
*{'main::'.$t} = sub (&;$) {
  my ($code, $next) = @_;
  unless ( defined wantarray ) {
     return _tag($t, $code, $next);
  } else {
     return bless sub {
        return _tag($t, $code, $next)
     }, 'MyTag';
  }
};
Пром-представления


package MyTag;
use overload 'quot;quot;' => sub {
  return buffered($_[0])
};
1;
Пром-представления

  a {'head'}
  b {'middle'}
   c {'tail'};
im_represent.pl
Экранирование
Экранирование

sub _escape {
  return unless defined $_[0];
  my $v = shift;
  $v = „$v”;
       „$v”;
  $v =~ s/.../.../g;
  return $v;
}
Экранирование

sub escape(@_) {
  return map
    blessed($_)
    && $_->isa('MyTag')
      ? $_ : _escape($_),
  @_;
}
Экранирование
sub buffered {
  ...
  return join '', $buf,
escape(@tail);
}
sub _tag {
  my ($tag, $code, $next) = @_;
  ...
  print join '', $res, escape $next;
}
Все работает
 escaping.pl
На закуску к экранам


sub outs(@) { print _escape(join '', @_) }

sub raw(@) { print join '', @_ }

# грабли №3
div { outs('some'); div {...} };
MyTD готов.
 Осталось
 только...
Недостающие части

объединить все примеры
запаковать все

sub template($$);
# template 'index' => run {};
sub show($@);
# show 'index', arg => $arg, ...;
Посмотреть

Template::Declare
Jifty::Dispatcher
Jifty::Param::Schema
Jifty::DBI::Schema
Object::Declare
B::*
ВСЕ
Вопросы?

More Related Content

What's hot

Estadistica cto 7
Estadistica cto 7Estadistica cto 7
Estadistica cto 7Luis Medina
 
Microsoft word -_lmn_tq
Microsoft word -_lmn_tqMicrosoft word -_lmn_tq
Microsoft word -_lmn_tqssuser2e4a96
 
(ISIA 3) Cours d'algorithmique (1995)
(ISIA 3) Cours d'algorithmique (1995)(ISIA 3) Cours d'algorithmique (1995)
(ISIA 3) Cours d'algorithmique (1995)Frank Nielsen
 
Аккредитация в достижении признания результатов оценки соответствия
Аккредитация в достижении признания результатов оценки соответствияАккредитация в достижении признания результатов оценки соответствия
Аккредитация в достижении признания результатов оценки соответствияiskandaruz
 
Uso da TC nas Fraturas Faciais.
Uso da TC nas Fraturas Faciais.Uso da TC nas Fraturas Faciais.
Uso da TC nas Fraturas Faciais.LABMF -PE
 
Bai Giang 8
Bai Giang 8Bai Giang 8
Bai Giang 8nbb3i
 
iReport實做練習part(1)
iReport實做練習part(1) iReport實做練習part(1)
iReport實做練習part(1) seatof
 
การใช้ Turbo C ชุดที่ 8 Array
การใช้ Turbo C ชุดที่ 8 Arrayการใช้ Turbo C ชุดที่ 8 Array
การใช้ Turbo C ชุดที่ 8 ArrayKnow Mastikate
 
DS-019-機械設計基礎(簡體)Ok
DS-019-機械設計基礎(簡體)OkDS-019-機械設計基礎(簡體)Ok
DS-019-機械設計基礎(簡體)Okhandbook
 
241 Ch
241 Ch241 Ch
241 Chanjaan
 
창의적 기업문화를 말하다
창의적 기업문화를 말하다창의적 기업문화를 말하다
창의적 기업문화를 말하다Jinho Jung
 
20101114 synchronizing automata_volkov_lecture03
20101114 synchronizing automata_volkov_lecture0320101114 synchronizing automata_volkov_lecture03
20101114 synchronizing automata_volkov_lecture03Computer Science Club
 
Baz sagir wa kabir yaseen akhtar misbahi--22 sep
Baz sagir wa kabir  yaseen akhtar misbahi--22 sepBaz sagir wa kabir  yaseen akhtar misbahi--22 sep
Baz sagir wa kabir yaseen akhtar misbahi--22 sepsunnicreative
 

What's hot (19)

Estadistica cto 7
Estadistica cto 7Estadistica cto 7
Estadistica cto 7
 
Rating Bar in Android Example
Rating Bar in Android ExampleRating Bar in Android Example
Rating Bar in Android Example
 
Microsoft word -_lmn_tq
Microsoft word -_lmn_tqMicrosoft word -_lmn_tq
Microsoft word -_lmn_tq
 
(ISIA 3) Cours d'algorithmique (1995)
(ISIA 3) Cours d'algorithmique (1995)(ISIA 3) Cours d'algorithmique (1995)
(ISIA 3) Cours d'algorithmique (1995)
 
Аккредитация в достижении признания результатов оценки соответствия
Аккредитация в достижении признания результатов оценки соответствияАккредитация в достижении признания результатов оценки соответствия
Аккредитация в достижении признания результатов оценки соответствия
 
P (1)
P (1)P (1)
P (1)
 
Uso da TC nas Fraturas Faciais.
Uso da TC nas Fraturas Faciais.Uso da TC nas Fraturas Faciais.
Uso da TC nas Fraturas Faciais.
 
Fiqh e Islami
Fiqh e IslamiFiqh e Islami
Fiqh e Islami
 
JUNTOS SOMOS MELHORES - RICK WARREN
JUNTOS SOMOS MELHORES -  RICK WARREN JUNTOS SOMOS MELHORES -  RICK WARREN
JUNTOS SOMOS MELHORES - RICK WARREN
 
Bai Giang 8
Bai Giang 8Bai Giang 8
Bai Giang 8
 
iReport實做練習part(1)
iReport實做練習part(1) iReport實做練習part(1)
iReport實做練習part(1)
 
การใช้ Turbo C ชุดที่ 8 Array
การใช้ Turbo C ชุดที่ 8 Arrayการใช้ Turbo C ชุดที่ 8 Array
การใช้ Turbo C ชุดที่ 8 Array
 
DS-019-機械設計基礎(簡體)Ok
DS-019-機械設計基礎(簡體)OkDS-019-機械設計基礎(簡體)Ok
DS-019-機械設計基礎(簡體)Ok
 
241 Ch
241 Ch241 Ch
241 Ch
 
창의적 기업문화를 말하다
창의적 기업문화를 말하다창의적 기업문화를 말하다
창의적 기업문화를 말하다
 
20101114 synchronizing automata_volkov_lecture03
20101114 synchronizing automata_volkov_lecture0320101114 synchronizing automata_volkov_lecture03
20101114 synchronizing automata_volkov_lecture03
 
Politrop
PolitropPolitrop
Politrop
 
Baz sagir wa kabir yaseen akhtar misbahi--22 sep
Baz sagir wa kabir  yaseen akhtar misbahi--22 sepBaz sagir wa kabir  yaseen akhtar misbahi--22 sep
Baz sagir wa kabir yaseen akhtar misbahi--22 sep
 
Satyanarayana Puja
Satyanarayana PujaSatyanarayana Puja
Satyanarayana Puja
 

Viewers also liked

Ведение документации в perl6: POD, да не тот !
Ведение документации в perl6: POD, да не тот !Ведение документации в perl6: POD, да не тот !
Ведение документации в perl6: POD, да не тот !mayperl
 
Wymiana Polsko Włoska 2
Wymiana Polsko Włoska 2Wymiana Polsko Włoska 2
Wymiana Polsko Włoska 2Carlissian
 
Распределенная обработка потоковых данных
Распределенная обработка потоковых данныхРаспределенная обработка потоковых данных
Распределенная обработка потоковых данныхmayperl
 
where the wild webmasters are
where the wild webmasters arewhere the wild webmasters are
where the wild webmasters arePweng Bee
 
Курс Perl в УрГУ
Курс Perl в УрГУКурс Perl в УрГУ
Курс Perl в УрГУmayperl
 
Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎mayperl
 
Perl в хэке и хэки в Perl
Perl в хэке и хэки в PerlPerl в хэке и хэки в Perl
Perl в хэке и хэки в Perlmayperl
 
Использование WebMoney в Perl‎
Использование WebMoney в Perl‎Использование WebMoney в Perl‎
Использование WebMoney в Perl‎mayperl
 
Сравнение работы алгоритмов сортировки, реализованных на Perl
Сравнение работы алгоритмов сортировки, реализованных на PerlСравнение работы алгоритмов сортировки, реализованных на Perl
Сравнение работы алгоритмов сортировки, реализованных на Perlmayperl
 
Use Perl like Perl
Use Perl like PerlUse Perl like Perl
Use Perl like Perlmayperl
 
Anyevent
AnyeventAnyevent
Anyeventmayperl
 
Perl + nginx = ♥‎
Perl + nginx = ♥‎Perl + nginx = ♥‎
Perl + nginx = ♥‎mayperl
 
IMAGES Foto-Ausstellungen 2011
IMAGES Foto-Ausstellungen 2011IMAGES Foto-Ausstellungen 2011
IMAGES Foto-Ausstellungen 2011edu.support
 
А у нас Perl 6 в production :)
А у нас Perl 6 в production :)А у нас Perl 6 в production :)
А у нас Perl 6 в production :)mayperl
 
The Story of the Bamboo
The Story of the BambooThe Story of the Bamboo
The Story of the BambooPweng Bee
 

Viewers also liked (16)

Ведение документации в perl6: POD, да не тот !
Ведение документации в perl6: POD, да не тот !Ведение документации в perl6: POD, да не тот !
Ведение документации в perl6: POD, да не тот !
 
Wymiana Polsko Włoska 2
Wymiana Polsko Włoska 2Wymiana Polsko Włoska 2
Wymiana Polsko Włoska 2
 
Распределенная обработка потоковых данных
Распределенная обработка потоковых данныхРаспределенная обработка потоковых данных
Распределенная обработка потоковых данных
 
where the wild webmasters are
where the wild webmasters arewhere the wild webmasters are
where the wild webmasters are
 
Курс Perl в УрГУ
Курс Perl в УрГУКурс Perl в УрГУ
Курс Perl в УрГУ
 
Prezentacja01
Prezentacja01Prezentacja01
Prezentacja01
 
Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎
 
Perl в хэке и хэки в Perl
Perl в хэке и хэки в PerlPerl в хэке и хэки в Perl
Perl в хэке и хэки в Perl
 
Использование WebMoney в Perl‎
Использование WebMoney в Perl‎Использование WebMoney в Perl‎
Использование WebMoney в Perl‎
 
Сравнение работы алгоритмов сортировки, реализованных на Perl
Сравнение работы алгоритмов сортировки, реализованных на PerlСравнение работы алгоритмов сортировки, реализованных на Perl
Сравнение работы алгоритмов сортировки, реализованных на Perl
 
Use Perl like Perl
Use Perl like PerlUse Perl like Perl
Use Perl like Perl
 
Anyevent
AnyeventAnyevent
Anyevent
 
Perl + nginx = ♥‎
Perl + nginx = ♥‎Perl + nginx = ♥‎
Perl + nginx = ♥‎
 
IMAGES Foto-Ausstellungen 2011
IMAGES Foto-Ausstellungen 2011IMAGES Foto-Ausstellungen 2011
IMAGES Foto-Ausstellungen 2011
 
А у нас Perl 6 в production :)
А у нас Perl 6 в production :)А у нас Perl 6 в production :)
А у нас Perl 6 в production :)
 
The Story of the Bamboo
The Story of the BambooThe Story of the Bamboo
The Story of the Bamboo
 

More from mayperl

‎Тестирование в проекте REG.RU‎
‎Тестирование в проекте REG.RU‎‎Тестирование в проекте REG.RU‎
‎Тестирование в проекте REG.RU‎mayperl
 
Browser sniffing в 21 веке‎
Browser sniffing в 21 веке‎Browser sniffing в 21 веке‎
Browser sniffing в 21 веке‎mayperl
 
Что будет с Перлом?
Что будет с Перлом?Что будет с Перлом?
Что будет с Перлом?mayperl
 
Вебклуб Perlgolf.ru
Вебклуб Perlgolf.ruВебклуб Perlgolf.ru
Вебклуб Perlgolf.rumayperl
 
Making Your Own CPAN
Making Your Own CPANMaking Your Own CPAN
Making Your Own CPANmayperl
 
Упаковка и развертывание программ на perl под debian‎
Упаковка и развертывание программ на perl под debian‎Упаковка и развертывание программ на perl под debian‎
Упаковка и развертывание программ на perl под debian‎mayperl
 
Groovy Vs Perl
Groovy Vs PerlGroovy Vs Perl
Groovy Vs Perlmayperl
 
10.000 вариантов снять квартиру или сам себе POE-риелтор
10.000 вариантов снять квартиру или сам себе POE-риелтор10.000 вариантов снять квартиру или сам себе POE-риелтор
10.000 вариантов снять квартиру или сам себе POE-риелторmayperl
 

More from mayperl (8)

‎Тестирование в проекте REG.RU‎
‎Тестирование в проекте REG.RU‎‎Тестирование в проекте REG.RU‎
‎Тестирование в проекте REG.RU‎
 
Browser sniffing в 21 веке‎
Browser sniffing в 21 веке‎Browser sniffing в 21 веке‎
Browser sniffing в 21 веке‎
 
Что будет с Перлом?
Что будет с Перлом?Что будет с Перлом?
Что будет с Перлом?
 
Вебклуб Perlgolf.ru
Вебклуб Perlgolf.ruВебклуб Perlgolf.ru
Вебклуб Perlgolf.ru
 
Making Your Own CPAN
Making Your Own CPANMaking Your Own CPAN
Making Your Own CPAN
 
Упаковка и развертывание программ на perl под debian‎
Упаковка и развертывание программ на perl под debian‎Упаковка и развертывание программ на perl под debian‎
Упаковка и развертывание программ на perl под debian‎
 
Groovy Vs Perl
Groovy Vs PerlGroovy Vs Perl
Groovy Vs Perl
 
10.000 вариантов снять квартиру или сам себе POE-риелтор
10.000 вариантов снять квартиру или сам себе POE-риелтор10.000 вариантов снять квартиру или сам себе POE-риелтор
10.000 вариантов снять квартиру или сам себе POE-риелтор
 

Написание DSL в Perl