SlideShare a Scribd company logo
Динамические возможности языка
                    Perl
            Есть ли что-то, чего нельзя сделать в Perl?

                              Валерий Студенников,
                                  despair@reg.ru


                                      May 2010



Динамические возможности языка Perl                       1/39
История доклада
                                                                                                                                                                                                                                       ЛЮБУЮ фичу можно рассматривать
                                                                                                                                                                                                                                       как преимущество, так и как
                                                                                                                                                Замыкания                                                                              недостаток
                                                                                                  Создание модулей, классов,                                                                                                           Невозможно быть 100%
                                                                                                  функций, переменных runtime       Компиляция "на лету"                                                                               объективным, весь мир
                                                                                                                                 Операции с symbol table     Например...                                                               IT-технологий субъективен
                                                                                                                                                                                                                                       Не хочу разводить holywar
                                                                                                                         Devel::Declare -- создание
                                                                                                                                                                           Динамические              Замечания по докладу
                                                                                                                         дополнительных синтаксических                                                                                 Каждый использует то, что
                                                                                                                         конструкций                                       возможности                                                 ему ближе
                                                                                                                                   Mechanism, not policy                                                                               Хочу донести некоторые
                                                                                                    Moose     Например свой ОО                              В результате                                                               соображения, которые можно
                                                                                                                                                                                                                                       принять или не принимать
                                                                                                         Например, продвинутый           можно делать ВСЁ
                                                                                                         шаблонизатор (TT)


                                                                                                                                                                                                                                   Очень просто обращаться
                                                                                                                          80000 модулей
                                                                                                                                                                                                   Встроенные структуры            Прозрачная конвертация
                                                                                                                   20000 дистрибутивов        CPAN     Готовые библиотеки                          данных                          в/из JSON, YAML
                                                                                                         Охвачены все сферы примения
                                                                                                                                                                                                                                   Не нужны доп. библиотеки           Возможность писать на "голом" Perl

                                                                                            5000 модулей на CPAN           Тестирование против        Динамическая                                                                                         Операции над списками
                                                                                            связанных с тестированием      статичной типизации        типизация                                                                Высокоуровневые
                                                                                                                                                                                                                               возможности                 Цепочные конструкции
                                                                                                                 Скорость                                                                                                                                  Regexps
                                                                                                                 разработки
                                                                                                                 Объём кода                                                          "Преимущества Perl" 1                                                       ФП     "Higher Order Perl"

                                                                                                                   More Fun                                                                                                                                                ООП можно делать "под
                                                                                                                                 Ключевые преимущества                                                                                                           ООП       себя" какое угодно
                    Кроме вычислительных                                                                                                                                                                                   Мультипарадигменность
                                                                                                   Форусировка на задаче 2
  Full-stack   Прекрасно подходит для web                                                          задачи, а не на языке                                                                                                                                         Процедурное
                                                                                                   решения                                                                                                                                                       "Бесструктурное"
               Подходит для бизнес-логики    Подходит для любых задач
  Web-приложения
                                                                                                                                                                                                                                                                                              По крайней мере для бизнес
  Сетевые демоны      Один язык для всего                                                                                                                                                                                                                                     Достаточная     логики и web -- более чем
    CRON-скрипты                                                                                                                                                                                                                             Производительность               Критичные участки можно
                                                                        Доп. преимущества                                                                                                                                                                                     писать на C/C++ (XS)         XS сложен   Inline прост
                                             Кросс-платформенность из
                                             коробки
                                                                                                                                                                                                                                  TIMTOWTDI          "Mechanism not policy"
                                         Прекрасная поддержка unicode                                                                                                                                                             "Насыщенный" код
                 Идеален для oneliners                                                                                                                                                                                            Perl hackers
                                         Великолепно "Масштабируется"
      Подходит для больших проектов                                                                                                                                                                                More Fun
                                                                                                                                                                                                                                  Адекватное коммьюнити

                                                                                       http://123.writeboard.com/470b8ce9d41307670                                                                                                DWIM

                                                                                      http://www.slideshare.net/aspushkin/perl-vs-java       Ресурсы по теме                                                                      Obfuscations
                                                                                            http://www.perl.com/pub/a/1999/03/pm.html
                                                                                                                                                                                                             Кривая обучения
                                                                                                                                  Yandex
                                                                                                                                                                                                                                              Punctiation variables
                                                                                                                                 Rambler                                                                     Много "исторического мусора"
                                                                                                                                                                                                                                              Formats
                                                                                                                              LiveJournal
                                                                                                                                                                                                                                            Требует самодисциплины и
                                                                                                                                   Mail.ru                                                                   Сопровождабельность кода       квалификации
                                                                                                      Rucenter                                                                                                                                                   POE
                                                                                                        Reg.ru
                                                                                                                                                Крупные проекты
                                                                                                                                                                                                                                                                 IO::Lambda
                                                                                                                  Регистраторы доменов                                                                       Не очень удачная    Зато прекрасная работа с
                                                                                                    Webnames                                                                                                 мультитредовость    асинхронным IO                  Coro
                                                                                                    Masterhost                                                                                                                                                   AnyEvent
                                                                                               Мало новых больших/успешных проектов                                                                                                                              IO::AIO
                                                                                               публично анонсирующих использование
                                                                                               perl                                                                                        Недостатки        Любую фичу можно
                                                                                                                                                                                                             рассматривать как недостаток
                                                                                                                                                                                                             ;)
                                                                                                                                                                                                                                             Бывает, трудно найти САМОЕ
                                                                                                                                                                                                             Неудобный поиск модулей на      подходящее решение
                                                                                                                                                                                                             CPAN (их СЛИШКОМ много)         Часть модулей устарела, не
                                                                                                                                                                                                                                             обновляется
                                                                                                                                                                                                             Отсутствие удобоваримго
                                                                                                                                                                                                             дешёвого хостинга            Однако, есть VPS...
                                                                                                                                                                                                             Не так удобно выкладывать      Дополнительно повышает
                                                                                                                                                                                                             на хостинг, как PHP            "планку входа"
                                                                                                                                                                                                             Большое количество
                                                                                                                                                                                                             информации о морально
                                                                                                                                                                                                             устаревших подходах         CGI.pm...




Динамические возможности языка Perl                                                                                                                                                                                                                                                                                                   2/39
Динамический язык?
   Динамический язык позволяет осуществлять
 синтаксический анализ и компиляцию "на лету",
 непосредственно на этапе выполнения
 (c) Wikipedia

 Динамический язык позволяет менять код / структуру
 программы во время выполнения;
         Perl динамический язык (но почему-то
         отсутствовал в Wikipedia в списке динамических
         языков!);
         В Perl На лету (уже после загрузки /
         компиляции приложения) можно делать ВСЁ.
Динамические возможности языка Perl                       3/39
Символические ссылки




       Символические ссылки...



Динамические возможности языка Perl   4/39
Символические ссылки
 ${ $ref } @{ $ref } %{ $ref } &{ $ref }

 ${ $str } @{ $str } %{ $str } &{ $str }
 # no s t r i c t , s h o u l d b u i l d & r u n ok
 our $ f r e d ;
 $b = " f r e d " ;
 $a = $$b ;
 $c = ${" d e f " } ;
 $c = @{" d e f " } ;
 $c = %{" d e f " } ;
 $c = ∗{ " d e f " } ;
 $c = &{" d e f " } ;
Динамические возможности языка Perl                    5/39
Как избежать предупреждений
  ${ ’XXX ’ } = 1 2 3 ;

 Получаем:
  Can’t use string ("XXX") as a SCALAR ref
 while "strict refs" in use at - line YYY

 # Боремся так :
 {
    no s t r i c t ’ r e f s ’ ;
    # Здесь делаем грязные дела. . .
 }

Динамические возможности языка Perl          6/39
Обращение к переменной по имени

  $ v a r = 1 2 3 ; @var = ( 1 ) ; %v a r = ( 1 , 2 ) ;
  $name = ’ v a r ’ ;
 Обратимся через символически ссылки:
  pr i nt ${$name } , @{$name } , %{$name } ;
  pr i nt ${__PACKAGE__. ’ : : ’ . $name } ;
 Ну и докучи через eval:
  pr i nt eval ’ $name ’ ;
 А можно ешё через typeglob, но об это позже...

Динамические возможности языка Perl                       7/39
Присваивание переменным на лету

  o u r $myname = 1 ;
  $varname = ’ myname ’ ;
 Опять используем символически ссылки:
  ${ $varname } = 1 2 3 ;
  ${__PACKAGE__. ’ : : ’ . $varname } = 1 2 3 ;
 Опять же через eval:
  eval “  $$varname = 123 ” ;
 Про typeglob всё-таки попозже...

Динамические возможности языка Perl               8/39
Typeglobs




                              Typeglobs...



Динамические возможности языка Perl          9/39
Typeglobs
Общее понятие



 package MyPkg ;

 $abc = 1 ;
 @abc = ( 1 , 2 ) ;
 %abc = ( a => ’A ’ ) ;
 sub abc { return ; }

  s a y ∗ abc ;
  s a y ∗MyPkg : : abc ;


Динамические возможности языка Perl   10/39
Typeglobs
Typeglobs как lvalue


 SYNOPSIS:
  ∗ t h i s = ∗that ;
  ∗ f o o = ∗STDOUT;

  ∗ foo      =     $bar ;
  ∗ foo      =     @bar ;
  ∗ foo      =    %b a r ;
  ∗ foo      =    &b a r ;

  l o c a l ∗ Here : : b l u e =  $There : : g r e e n ;

Динамические возможности языка Perl                         11/39
Typeglobs
Все способы получить доступ к значению typeglob

 package A ;
 o u r $a = 1 2 3 ;

  say      ${     ∗a } ;
  say      ${     ∗A : : a } ;
  say      ${     ∗{A : : a } } ;
  say      ${     ∗{ ’A : : a ’ } } ;
  say      ${     ∗{ ’A : : a ’ }{SCALAR} } ;
  say      ${     $ {∗A : : } { a } } ;

  o u r @a = ( 1 , 2 , 3 ) ;
  s a y @{ ∗a } ;
Динамические возможности языка Perl               12/39
Typeglobs
Присваивание, локализация

  $spud             = "Wow! " ;
  @spud             = (" idaho " , " r u s s e t " ) ;
 Алиасим potato −→ spud через typeglob:
 ∗ p o t a t o = ∗ spud ;
 s a y $ p o t a t o ; # p r i n t s "Wow! "
 s a y @potato ; # p r i n t s " i d a h o r u s s e t "
 Инкремент $a неявно через typeglob и ссылку:
 $a = 1 0 ;
 ∗b = ∗a ; $b++ ;
 $ r =  $a ; $ $ r ++;
Динамические возможности языка Perl                        13/39
Просмотр содержимого namespace
 package A ;
 o u r @a = ( 1 , 2 , 3 ) ;
 sub two { 2 } ;

 package main ;
 pr i nt Dumper(%{∗{A : : } } ) ; # A : : t y p e g l o b
 Prints:
 $VAR1 = {
     ’a’ => *A::a,
     ’two’ => *A::two
 };
Динамические возможности языка Perl                      14/39
Просмотр содержимого namespace
 Ключи хеша typeglob:

   SCALAR           скаляр                 IO файлхендл
    ARRAY           массив
                                      PACKAGE название
     HASH           хэш
                                             пакета
     CODE           функция
  FORMAT            формат              NAME имя в таблице
     GLOB           ссылка на себя           имён

 o u r @a = ( 1 , 2 , 3 ) ;
 pr i nt Dumper ( ∗a {ARRAY} ) ;
 # $VAR1 = [ 1 , 2 , 3 ] ;

Динамические возможности языка Perl                       15/39
Динамический вызов функций / методов




             Динамический вызов
             функций / методов...


Динамические возможности языка Perl   16/39
Вызов функции / метода по имени
  sub s q r { $_ [ 0 ] ∗ $_ [ 0 ] }
 Вызов функции по имени:
 $subname = ’ s q r ’ ;
 $subname − >(2);
 &$subname ( 2 ) ;
 ∗{ $subname } − >(2);
 &{ ∗{ $subname } } ( 2 ) ;
 Вызов функции определённого пакета:
 __PACKAGE__−>$subname ( 2 ) ;
 main−>$subname ( 2 ) ;
 Вызов метода по имени:
  $ o b j e c t −>$subname ( 2 ) ;
Динамические возможности языка Perl    17/39
Вызов функции из неизвестного пакета
 Имя функции известно заранее:
  $package−>a c t i o n ( ) ;

 Имя функции заранее не известно:
 $ f u l l n a m e = $ p a c k a g e . ’ : : ’ . $subname ;
 $subname = ’ s q r ’ ;
 $ f u l l n a m e −>( @ a r g s ) ;
 &$ f u l l n a m e ( @ a r g s ) ;
 ∗{ $ f u l l n a m e }−>( @ a r g s ) ;
 &{ ∗{ $ f u l l n a m e } } ( @ a r g s ) ;

 Ещё один синтаксис1 :
  $package−>$subname ( @ a r g s ) ;

     1
         Внимание, первым аргументом будет передано название пакета!
Динамические возможности языка Perl                                    18/39
Получить ссылку на функцию

  $packagename = ’ MyPackage ’ ;
  $subname = ’ s q r ’ ;
 Из своего пакета:
  $ r e f = &{$subname } ; # Предпочтительнее
  $ r e f = ∗{ $subname } ;
 Из чужого пакета:
  $ r e f = &{ $packagename . ’ : : ’ . $subname } ;
  $ r e f = ∗{ $packagename . ’ : : ’ . $subname } ;


Динамические возможности языка Perl                 19/39
Вызов функции по ссылке

 my $ r e f ; # Ссылка на функцию

  $ r e f −>( @args ) ;

 &$ r e f ( @args ) ;

  goto &$ r e f ; # Останется текущий @_
  goto &$AUTOLOAD ;



Динамические возможности языка Perl        20/39
Запись функции в пространство имён
  $subname = ’ a l i a s ’ ; $packagname = ’ MyPackage ’ ;
 Записываем в namespace текущего пакета:
 ∗{ $subname } = & s q r ;
 alias ( 4 );
 Записываем в namespace произвольного пакета:
 ∗{ "${ packagname } : : $subname "} = $ c o d e r e f ;
 $packagname−> a l i a s ( 2 ) ;
 Переопределяем стандартные функции:
 ∗system = &mysub ;
 ∗ d i e = ∗CORE : : d i e ;
 ∗CORE : : GLOBAL : : d i e = sub {
        warn "You t r i e d t o d i e w i t h ’@_ ’ "
 };
Динамические возможности языка Perl                          21/39
Способы переопределения функции
  ∗{ "A : : t e s t "} = $ c o d e r e f ;

  package A ;
  sub t e s t { 1 } ;
  package B ;
  sub A : : t e s t { 2 } ;
  print A : : t e s t ( ) ; # p r i n t s 2

  package A ;
  sub t e s t { 1 } ;
  ...
  package A ;
  sub t e s t { 2 } ;
  package B ;
  print A : : t e s t ( ) ; # p r i n t s 2
Динамические возможности языка Perl           22/39
Замыкания

 sub outer_sub
 {
     my $ v a r i a b l e = s h i f t ;

           sub i n n e r _ s u b {
               print $ v a r i a b l e ;
           }
  }



Динамические возможности языка Perl        23/39
Замыкания
Использование для accessors



 sub _get {
     my ( $ s e l f , $ f l d n a m e ) = @_;
     ...
 }

  $obj −>_get ( ’ username ’ ) ;

 # Делаем короткий алиас
 $obj −>get_username ;


Динамические возможности языка Perl             24/39
Замыкания
Пример применения замыканий: accessors


  sub make_ro_accessor {
    my( $ c l a s s , $ f i e l d ) = @_;

     my $ s u b r e f = sub { # Обёртка для _get
        my $ s e l f = s h i f t ;
        return &{∗{"${ c l a s s } : : _get " } }( $ s e l f , $ f i e l d ) ;
     };

      ∗{ "${ c l a s s } : : g e t _ $ f i e l d "} = $ s u b r e f ;
 }
 __PACKAGE__−>make_ro_accessor ( ’ username ’ )

  p r i n t $ o b j −>get_username ;

Динамические возможности языка Perl                                      25/39
Выполнение произвольного кода
 eval {} используется для отлова исключений:
  eval { d o s t u f f ( ) } ;
  i f ( $@ ) { c o m p l a i n ( ) }

 eval "" выполняет произвольный код:
  eval " p r i n t 123 " ;
 Не нужно злоупотреблять!
 Пример             создадим функцию на лету:
  eval ’ sub s q r { $_ [ 0 ] ∗ $_ [ 0 ] } ’ ;
  pr i nt s q r ( 2 ) ;
Динамические возможности языка Perl              26/39
Выполнение кода из файла
 Загрузить и выполнить содержимое файла:
 do $ f i l e n a m e ;
 Эквивалент "do":
 eval ‘ c a t $ f i l e n a m e ‘
 Так можно сделать простейшие конфиги
 (хотя это и не рекомендуемая практика):
 $config = (
    dbname => ’ t e s t ’ ,
    username => ’ t e s t ’ ,
    p a s s => ’ s d s f d f ’
 );
Динамические возможности языка Perl        27/39
%INC
  p e r l −MData : : Dumper −e ’ p r i n t Dumper ( %INC ) ’

 $VAR1 = {
   ’warnings/register.pm’ => ’/usr/lib/perl5/5.10.0/warnin
   ’bytes.pm’ => ’/usr/lib/perl5/5.10.0/bytes.pm’,
   ’XSLoader.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-thre
   ’Data/Dumper.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-t
   ...
 };

  p e r l −MCGI −e ’ p r i n t j o i n "n" , s o r t k e y s %INC ’

 CGI.pm
 CGI/Util.pm
 Carp.pm
 ...
Динамические возможности языка Perl                               28/39
@INC

  p e r l −e ’ p r i n t j o i n "n" , @INC ; ’

 /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-m
 /usr/local/lib/perl5/site_perl/5.10.0
 /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi
 /usr/lib/perl5/vendor_perl/5.10.0
 /usr/lib/perl5/vendor_perl
 /usr/lib/perl5/5.10.0/i386-linux-thread-multi
 /usr/lib/perl5/5.10.0
 /usr/lib/perl5/site_perl



Динамические возможности языка Perl                  29/39
Подгрузка модулей на лету
  require $ f i l e n a m e ;
 Безопасная одноразовая загрузка модулей:
  sub use_once ( $ ) {
      my ( $module ) = @_;

         my $ f i l e n a m e = $module . ’ . pm ’ ;
         $ f i l e n a m e =~ s / : : /  / / xmsg ;

          u n l e s s ( $INC { $ f i l e n a m e } ) {
                  e v a l { r e q u i r e $ f i l e n a m e } o r return ;
                  import $module ;
          }
          return 1 ;
  }
Динамические возможности языка Perl                                          30/39
AUTOLOAD
Пример 1



 sub AUTOLOAD
 {
   o u r $AUTOLOAD ;

      return " I s e e $AUTOLOAD(@_) n" ;
  }

 pr i nt b l a r g ( 1 2 3 ) ;
 # prints         I s e e main : : b l a r g ( 1 2 3 )


Динамические возможности языка Perl                      31/39
AUTOLOAD
Пример 2



  sub AUTOLOAD {
    my $ p a c k a g e = s h i f t @_;
    my $name = o u r $AUTOLOAD ;

      ∗$AUTOLOAD = sub { p r i n t " I s e e $name (@_)  n" } ;
       goto &$AUTOLOAD ; # R e s t a r t t h e new r o u t i n e
  }

  blarg (30);                # p r i n t s : I s e e main : : b l a r g ( 3 0 )
  glarb (40);                # p r i n t s : I s e e main : : g l a r b ( 4 0 )
  blarg (50);                # p r i n t s : I s e e main : : b l a r g ( 5 0 )


Динамические возможности языка Perl                                               32/39
overload
Переопределение операторов языка




  use o v e r l o a d
      ’+ ’ => &myadd ,
      ’− ’ => &mysub ;

  use Number : : F r a c t i o n ’ : c o n s t a n t s ’

 my $ f 1 = ’ 1/2 ’ ;
 pr i nt $ f 1 + ‘ 1 /3 ’ ; # p r i n t s ’ 5 / 6 ’



Динамические возможности языка Perl                        33/39
Devel::Declare
 Определение новых ключевых слов / синтаксических
 конструкций.
 Например:
  method f o o ( $arg1 , $ a r g 2 ) {
      ...
  }
 =⇒
 sub f o o {
     my ( $ s e l f , $arg1 , $ a r g 2 ) = @_;
     ...
 }
Динамические возможности языка Perl                 34/39
PadWalker

 PadWalker               play with other peoples’ lexical variables
  peek_my LEVEL
  peek_our LEVEL
  peek_sub SUB
  c l o s e d _ o v e r SUB
  s e t _ c l o s e d _ o v e r SUB , HASH_REF
  var_name LEVEL , VAR_REF
  var_name SUB , VAR_REF



Динамические возможности языка Perl                                   35/39
Демонстрация возможностей Perl
Barely Legal XXX Perl


 Jos Boumans Barely Legal XXX Perl :
      Acme::BadExample
      Correct Syntax
      Impossible to run
      Tries to do very nasty things!
  p e r l −MAnti : : Code 
    −e ’ u s e Acme : : BadExample ; warn " done " ’
 Выполняется до конца, в конце выводит "done".
 Код возврата 0.
Динамические возможности языка Perl                    36/39
Демонстрация возможностей Perl
Barely Legal XXX Perl



                                                                 ∗CORE : : GLOBAL : : d i e = s u b {
 p a c k a g e A n t i : : Code ;                                   w a r n "You t r i e d t o d i e w i t h ’@_ ’ "
 BEGIN {                                                         };
    # stop compile e r r o r s                                   # fake our super c l a s s
     $INC { ’ s t r i c t . pm ’ } = 1 ;                         ∗SUPER : : new = s u b { {} } ;
     $INC { ’ w a r n i n g s . pm ’ } = 1 ;                     # d e f i n e a s u b t h a t i s u s e d a s a FH
    # l o a d dummy f i l e s t h a t do no harm                 ∗Acme : : BadExample : : FOO = s u b { l a s t } ;
     require less ;                                              # f o r c e a ‘ t r u e ’ v a l u e a t end o f f i l e
     u n s h i f t @INC , s u b {                                sub l e s s : : import {
         i f ( c a l l e r eq ’ Acme : : BadExample ’ ) {           use overload ;
             o p e n my $ f h , $INC { ’ l e s s . pm ’ }           overload : : constant (
                 or r e t u r n ;                                      q = s u b { $_ [ 1 ] | | 1 }
                                                                             >
             r e t u r n $fh ;                                      );
         }                                                       }
         return ;                                           }
     };                                                     1;
    # stop system c a l l s
    ∗CORE : : GLOBAL : : s y s t e m = s u b { 0 } ;
    # Never l e t i t d i e




Динамические возможности языка Perl                                                                              37/39
Что почитать

         perlmod :: Symbol Tables
         perldata :: Typeglobs and Filehandles
         Sriram Srinivasan Advanced Perl Programming ::
          Typeglobs and Symbol Tables
         by brian d foy Mastering Perl :: Symbol Tables
         and Typeglobs


         Оригинал презентации:
         https://svn.reg.ru/oss/presentation/devconf-2010/

Динамические возможности языка Perl                          38/39
КонецЪ


 use P e r l o r die ;
                            use LTEX 2ε;
                                A

                              Вопросы?
Динамические возможности языка Perl        39/39

More Related Content

PDF
Управление репутацией в соцмедиа
PPT
"Вежливые слова"
PDF
Perl Events
PDF
Резюме Стасенко А.П
PDF
Perl 5.16 and beyond by Jesse Vincent (Русская версия)
PPTX
Двухдневный тренинг «Веб-аналитика и интернет-продвижение Вашего бизнеса» – 2...
PPTX
YAPC Russia: Анализ памяти в perl
PDF
smcamp 2013 - работа с негативом в социальных сетях
Управление репутацией в соцмедиа
"Вежливые слова"
Perl Events
Резюме Стасенко А.П
Perl 5.16 and beyond by Jesse Vincent (Русская версия)
Двухдневный тренинг «Веб-аналитика и интернет-продвижение Вашего бизнеса» – 2...
YAPC Russia: Анализ памяти в perl
smcamp 2013 - работа с негативом в социальных сетях
Ad

Perl dynamic-features

  • 1. Динамические возможности языка Perl Есть ли что-то, чего нельзя сделать в Perl? Валерий Студенников, despair@reg.ru May 2010 Динамические возможности языка Perl 1/39
  • 2. История доклада ЛЮБУЮ фичу можно рассматривать как преимущество, так и как Замыкания недостаток Создание модулей, классов, Невозможно быть 100% функций, переменных runtime Компиляция "на лету" объективным, весь мир Операции с symbol table Например... IT-технологий субъективен Не хочу разводить holywar Devel::Declare -- создание Динамические Замечания по докладу дополнительных синтаксических Каждый использует то, что конструкций возможности ему ближе Mechanism, not policy Хочу донести некоторые Moose Например свой ОО В результате соображения, которые можно принять или не принимать Например, продвинутый можно делать ВСЁ шаблонизатор (TT) Очень просто обращаться 80000 модулей Встроенные структуры Прозрачная конвертация 20000 дистрибутивов CPAN Готовые библиотеки данных в/из JSON, YAML Охвачены все сферы примения Не нужны доп. библиотеки Возможность писать на "голом" Perl 5000 модулей на CPAN Тестирование против Динамическая Операции над списками связанных с тестированием статичной типизации типизация Высокоуровневые возможности Цепочные конструкции Скорость Regexps разработки Объём кода "Преимущества Perl" 1 ФП "Higher Order Perl" More Fun ООП можно делать "под Ключевые преимущества ООП себя" какое угодно Кроме вычислительных Мультипарадигменность Форусировка на задаче 2 Full-stack Прекрасно подходит для web задачи, а не на языке Процедурное решения "Бесструктурное" Подходит для бизнес-логики Подходит для любых задач Web-приложения По крайней мере для бизнес Сетевые демоны Один язык для всего Достаточная логики и web -- более чем CRON-скрипты Производительность Критичные участки можно Доп. преимущества писать на C/C++ (XS) XS сложен Inline прост Кросс-платформенность из коробки TIMTOWTDI "Mechanism not policy" Прекрасная поддержка unicode "Насыщенный" код Идеален для oneliners Perl hackers Великолепно "Масштабируется" Подходит для больших проектов More Fun Адекватное коммьюнити http://123.writeboard.com/470b8ce9d41307670 DWIM http://www.slideshare.net/aspushkin/perl-vs-java Ресурсы по теме Obfuscations http://www.perl.com/pub/a/1999/03/pm.html Кривая обучения Yandex Punctiation variables Rambler Много "исторического мусора" Formats LiveJournal Требует самодисциплины и Mail.ru Сопровождабельность кода квалификации Rucenter POE Reg.ru Крупные проекты IO::Lambda Регистраторы доменов Не очень удачная Зато прекрасная работа с Webnames мультитредовость асинхронным IO Coro Masterhost AnyEvent Мало новых больших/успешных проектов IO::AIO публично анонсирующих использование perl Недостатки Любую фичу можно рассматривать как недостаток ;) Бывает, трудно найти САМОЕ Неудобный поиск модулей на подходящее решение CPAN (их СЛИШКОМ много) Часть модулей устарела, не обновляется Отсутствие удобоваримго дешёвого хостинга Однако, есть VPS... Не так удобно выкладывать Дополнительно повышает на хостинг, как PHP "планку входа" Большое количество информации о морально устаревших подходах CGI.pm... Динамические возможности языка Perl 2/39
  • 3. Динамический язык? Динамический язык позволяет осуществлять синтаксический анализ и компиляцию "на лету", непосредственно на этапе выполнения (c) Wikipedia Динамический язык позволяет менять код / структуру программы во время выполнения; Perl динамический язык (но почему-то отсутствовал в Wikipedia в списке динамических языков!); В Perl На лету (уже после загрузки / компиляции приложения) можно делать ВСЁ. Динамические возможности языка Perl 3/39
  • 4. Символические ссылки Символические ссылки... Динамические возможности языка Perl 4/39
  • 5. Символические ссылки ${ $ref } @{ $ref } %{ $ref } &{ $ref } ${ $str } @{ $str } %{ $str } &{ $str } # no s t r i c t , s h o u l d b u i l d & r u n ok our $ f r e d ; $b = " f r e d " ; $a = $$b ; $c = ${" d e f " } ; $c = @{" d e f " } ; $c = %{" d e f " } ; $c = ∗{ " d e f " } ; $c = &{" d e f " } ; Динамические возможности языка Perl 5/39
  • 6. Как избежать предупреждений ${ ’XXX ’ } = 1 2 3 ; Получаем: Can’t use string ("XXX") as a SCALAR ref while "strict refs" in use at - line YYY # Боремся так : { no s t r i c t ’ r e f s ’ ; # Здесь делаем грязные дела. . . } Динамические возможности языка Perl 6/39
  • 7. Обращение к переменной по имени $ v a r = 1 2 3 ; @var = ( 1 ) ; %v a r = ( 1 , 2 ) ; $name = ’ v a r ’ ; Обратимся через символически ссылки: pr i nt ${$name } , @{$name } , %{$name } ; pr i nt ${__PACKAGE__. ’ : : ’ . $name } ; Ну и докучи через eval: pr i nt eval ’ $name ’ ; А можно ешё через typeglob, но об это позже... Динамические возможности языка Perl 7/39
  • 8. Присваивание переменным на лету o u r $myname = 1 ; $varname = ’ myname ’ ; Опять используем символически ссылки: ${ $varname } = 1 2 3 ; ${__PACKAGE__. ’ : : ’ . $varname } = 1 2 3 ; Опять же через eval: eval “ $$varname = 123 ” ; Про typeglob всё-таки попозже... Динамические возможности языка Perl 8/39
  • 9. Typeglobs Typeglobs... Динамические возможности языка Perl 9/39
  • 10. Typeglobs Общее понятие package MyPkg ; $abc = 1 ; @abc = ( 1 , 2 ) ; %abc = ( a => ’A ’ ) ; sub abc { return ; } s a y ∗ abc ; s a y ∗MyPkg : : abc ; Динамические возможности языка Perl 10/39
  • 11. Typeglobs Typeglobs как lvalue SYNOPSIS: ∗ t h i s = ∗that ; ∗ f o o = ∗STDOUT; ∗ foo = $bar ; ∗ foo = @bar ; ∗ foo = %b a r ; ∗ foo = &b a r ; l o c a l ∗ Here : : b l u e = $There : : g r e e n ; Динамические возможности языка Perl 11/39
  • 12. Typeglobs Все способы получить доступ к значению typeglob package A ; o u r $a = 1 2 3 ; say ${ ∗a } ; say ${ ∗A : : a } ; say ${ ∗{A : : a } } ; say ${ ∗{ ’A : : a ’ } } ; say ${ ∗{ ’A : : a ’ }{SCALAR} } ; say ${ $ {∗A : : } { a } } ; o u r @a = ( 1 , 2 , 3 ) ; s a y @{ ∗a } ; Динамические возможности языка Perl 12/39
  • 13. Typeglobs Присваивание, локализация $spud = "Wow! " ; @spud = (" idaho " , " r u s s e t " ) ; Алиасим potato −→ spud через typeglob: ∗ p o t a t o = ∗ spud ; s a y $ p o t a t o ; # p r i n t s "Wow! " s a y @potato ; # p r i n t s " i d a h o r u s s e t " Инкремент $a неявно через typeglob и ссылку: $a = 1 0 ; ∗b = ∗a ; $b++ ; $ r = $a ; $ $ r ++; Динамические возможности языка Perl 13/39
  • 14. Просмотр содержимого namespace package A ; o u r @a = ( 1 , 2 , 3 ) ; sub two { 2 } ; package main ; pr i nt Dumper(%{∗{A : : } } ) ; # A : : t y p e g l o b Prints: $VAR1 = { ’a’ => *A::a, ’two’ => *A::two }; Динамические возможности языка Perl 14/39
  • 15. Просмотр содержимого namespace Ключи хеша typeglob: SCALAR скаляр IO файлхендл ARRAY массив PACKAGE название HASH хэш пакета CODE функция FORMAT формат NAME имя в таблице GLOB ссылка на себя имён o u r @a = ( 1 , 2 , 3 ) ; pr i nt Dumper ( ∗a {ARRAY} ) ; # $VAR1 = [ 1 , 2 , 3 ] ; Динамические возможности языка Perl 15/39
  • 16. Динамический вызов функций / методов Динамический вызов функций / методов... Динамические возможности языка Perl 16/39
  • 17. Вызов функции / метода по имени sub s q r { $_ [ 0 ] ∗ $_ [ 0 ] } Вызов функции по имени: $subname = ’ s q r ’ ; $subname − >(2); &$subname ( 2 ) ; ∗{ $subname } − >(2); &{ ∗{ $subname } } ( 2 ) ; Вызов функции определённого пакета: __PACKAGE__−>$subname ( 2 ) ; main−>$subname ( 2 ) ; Вызов метода по имени: $ o b j e c t −>$subname ( 2 ) ; Динамические возможности языка Perl 17/39
  • 18. Вызов функции из неизвестного пакета Имя функции известно заранее: $package−>a c t i o n ( ) ; Имя функции заранее не известно: $ f u l l n a m e = $ p a c k a g e . ’ : : ’ . $subname ; $subname = ’ s q r ’ ; $ f u l l n a m e −>( @ a r g s ) ; &$ f u l l n a m e ( @ a r g s ) ; ∗{ $ f u l l n a m e }−>( @ a r g s ) ; &{ ∗{ $ f u l l n a m e } } ( @ a r g s ) ; Ещё один синтаксис1 : $package−>$subname ( @ a r g s ) ; 1 Внимание, первым аргументом будет передано название пакета! Динамические возможности языка Perl 18/39
  • 19. Получить ссылку на функцию $packagename = ’ MyPackage ’ ; $subname = ’ s q r ’ ; Из своего пакета: $ r e f = &{$subname } ; # Предпочтительнее $ r e f = ∗{ $subname } ; Из чужого пакета: $ r e f = &{ $packagename . ’ : : ’ . $subname } ; $ r e f = ∗{ $packagename . ’ : : ’ . $subname } ; Динамические возможности языка Perl 19/39
  • 20. Вызов функции по ссылке my $ r e f ; # Ссылка на функцию $ r e f −>( @args ) ; &$ r e f ( @args ) ; goto &$ r e f ; # Останется текущий @_ goto &$AUTOLOAD ; Динамические возможности языка Perl 20/39
  • 21. Запись функции в пространство имён $subname = ’ a l i a s ’ ; $packagname = ’ MyPackage ’ ; Записываем в namespace текущего пакета: ∗{ $subname } = & s q r ; alias ( 4 ); Записываем в namespace произвольного пакета: ∗{ "${ packagname } : : $subname "} = $ c o d e r e f ; $packagname−> a l i a s ( 2 ) ; Переопределяем стандартные функции: ∗system = &mysub ; ∗ d i e = ∗CORE : : d i e ; ∗CORE : : GLOBAL : : d i e = sub { warn "You t r i e d t o d i e w i t h ’@_ ’ " }; Динамические возможности языка Perl 21/39
  • 22. Способы переопределения функции ∗{ "A : : t e s t "} = $ c o d e r e f ; package A ; sub t e s t { 1 } ; package B ; sub A : : t e s t { 2 } ; print A : : t e s t ( ) ; # p r i n t s 2 package A ; sub t e s t { 1 } ; ... package A ; sub t e s t { 2 } ; package B ; print A : : t e s t ( ) ; # p r i n t s 2 Динамические возможности языка Perl 22/39
  • 23. Замыкания sub outer_sub { my $ v a r i a b l e = s h i f t ; sub i n n e r _ s u b { print $ v a r i a b l e ; } } Динамические возможности языка Perl 23/39
  • 24. Замыкания Использование для accessors sub _get { my ( $ s e l f , $ f l d n a m e ) = @_; ... } $obj −>_get ( ’ username ’ ) ; # Делаем короткий алиас $obj −>get_username ; Динамические возможности языка Perl 24/39
  • 25. Замыкания Пример применения замыканий: accessors sub make_ro_accessor { my( $ c l a s s , $ f i e l d ) = @_; my $ s u b r e f = sub { # Обёртка для _get my $ s e l f = s h i f t ; return &{∗{"${ c l a s s } : : _get " } }( $ s e l f , $ f i e l d ) ; }; ∗{ "${ c l a s s } : : g e t _ $ f i e l d "} = $ s u b r e f ; } __PACKAGE__−>make_ro_accessor ( ’ username ’ ) p r i n t $ o b j −>get_username ; Динамические возможности языка Perl 25/39
  • 26. Выполнение произвольного кода eval {} используется для отлова исключений: eval { d o s t u f f ( ) } ; i f ( $@ ) { c o m p l a i n ( ) } eval "" выполняет произвольный код: eval " p r i n t 123 " ; Не нужно злоупотреблять! Пример создадим функцию на лету: eval ’ sub s q r { $_ [ 0 ] ∗ $_ [ 0 ] } ’ ; pr i nt s q r ( 2 ) ; Динамические возможности языка Perl 26/39
  • 27. Выполнение кода из файла Загрузить и выполнить содержимое файла: do $ f i l e n a m e ; Эквивалент "do": eval ‘ c a t $ f i l e n a m e ‘ Так можно сделать простейшие конфиги (хотя это и не рекомендуемая практика): $config = ( dbname => ’ t e s t ’ , username => ’ t e s t ’ , p a s s => ’ s d s f d f ’ ); Динамические возможности языка Perl 27/39
  • 28. %INC p e r l −MData : : Dumper −e ’ p r i n t Dumper ( %INC ) ’ $VAR1 = { ’warnings/register.pm’ => ’/usr/lib/perl5/5.10.0/warnin ’bytes.pm’ => ’/usr/lib/perl5/5.10.0/bytes.pm’, ’XSLoader.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-thre ’Data/Dumper.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-t ... }; p e r l −MCGI −e ’ p r i n t j o i n "n" , s o r t k e y s %INC ’ CGI.pm CGI/Util.pm Carp.pm ... Динамические возможности языка Perl 28/39
  • 29. @INC p e r l −e ’ p r i n t j o i n "n" , @INC ; ’ /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-m /usr/local/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.10.0/i386-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/lib/perl5/site_perl Динамические возможности языка Perl 29/39
  • 30. Подгрузка модулей на лету require $ f i l e n a m e ; Безопасная одноразовая загрузка модулей: sub use_once ( $ ) { my ( $module ) = @_; my $ f i l e n a m e = $module . ’ . pm ’ ; $ f i l e n a m e =~ s / : : / / / xmsg ; u n l e s s ( $INC { $ f i l e n a m e } ) { e v a l { r e q u i r e $ f i l e n a m e } o r return ; import $module ; } return 1 ; } Динамические возможности языка Perl 30/39
  • 31. AUTOLOAD Пример 1 sub AUTOLOAD { o u r $AUTOLOAD ; return " I s e e $AUTOLOAD(@_) n" ; } pr i nt b l a r g ( 1 2 3 ) ; # prints I s e e main : : b l a r g ( 1 2 3 ) Динамические возможности языка Perl 31/39
  • 32. AUTOLOAD Пример 2 sub AUTOLOAD { my $ p a c k a g e = s h i f t @_; my $name = o u r $AUTOLOAD ; ∗$AUTOLOAD = sub { p r i n t " I s e e $name (@_) n" } ; goto &$AUTOLOAD ; # R e s t a r t t h e new r o u t i n e } blarg (30); # p r i n t s : I s e e main : : b l a r g ( 3 0 ) glarb (40); # p r i n t s : I s e e main : : g l a r b ( 4 0 ) blarg (50); # p r i n t s : I s e e main : : b l a r g ( 5 0 ) Динамические возможности языка Perl 32/39
  • 33. overload Переопределение операторов языка use o v e r l o a d ’+ ’ => &myadd , ’− ’ => &mysub ; use Number : : F r a c t i o n ’ : c o n s t a n t s ’ my $ f 1 = ’ 1/2 ’ ; pr i nt $ f 1 + ‘ 1 /3 ’ ; # p r i n t s ’ 5 / 6 ’ Динамические возможности языка Perl 33/39
  • 34. Devel::Declare Определение новых ключевых слов / синтаксических конструкций. Например: method f o o ( $arg1 , $ a r g 2 ) { ... } =⇒ sub f o o { my ( $ s e l f , $arg1 , $ a r g 2 ) = @_; ... } Динамические возможности языка Perl 34/39
  • 35. PadWalker PadWalker play with other peoples’ lexical variables peek_my LEVEL peek_our LEVEL peek_sub SUB c l o s e d _ o v e r SUB s e t _ c l o s e d _ o v e r SUB , HASH_REF var_name LEVEL , VAR_REF var_name SUB , VAR_REF Динамические возможности языка Perl 35/39
  • 36. Демонстрация возможностей Perl Barely Legal XXX Perl Jos Boumans Barely Legal XXX Perl : Acme::BadExample Correct Syntax Impossible to run Tries to do very nasty things! p e r l −MAnti : : Code −e ’ u s e Acme : : BadExample ; warn " done " ’ Выполняется до конца, в конце выводит "done". Код возврата 0. Динамические возможности языка Perl 36/39
  • 37. Демонстрация возможностей Perl Barely Legal XXX Perl ∗CORE : : GLOBAL : : d i e = s u b { p a c k a g e A n t i : : Code ; w a r n "You t r i e d t o d i e w i t h ’@_ ’ " BEGIN { }; # stop compile e r r o r s # fake our super c l a s s $INC { ’ s t r i c t . pm ’ } = 1 ; ∗SUPER : : new = s u b { {} } ; $INC { ’ w a r n i n g s . pm ’ } = 1 ; # d e f i n e a s u b t h a t i s u s e d a s a FH # l o a d dummy f i l e s t h a t do no harm ∗Acme : : BadExample : : FOO = s u b { l a s t } ; require less ; # f o r c e a ‘ t r u e ’ v a l u e a t end o f f i l e u n s h i f t @INC , s u b { sub l e s s : : import { i f ( c a l l e r eq ’ Acme : : BadExample ’ ) { use overload ; o p e n my $ f h , $INC { ’ l e s s . pm ’ } overload : : constant ( or r e t u r n ; q = s u b { $_ [ 1 ] | | 1 } > r e t u r n $fh ; ); } } return ; } }; 1; # stop system c a l l s ∗CORE : : GLOBAL : : s y s t e m = s u b { 0 } ; # Never l e t i t d i e Динамические возможности языка Perl 37/39
  • 38. Что почитать perlmod :: Symbol Tables perldata :: Typeglobs and Filehandles Sriram Srinivasan Advanced Perl Programming :: Typeglobs and Symbol Tables by brian d foy Mastering Perl :: Symbol Tables and Typeglobs Оригинал презентации: https://svn.reg.ru/oss/presentation/devconf-2010/ Динамические возможности языка Perl 38/39
  • 39. КонецЪ use P e r l o r die ; use LTEX 2ε; A Вопросы? Динамические возможности языка Perl 39/39