Perl dynamic-features
Upcoming SlideShare
Loading in...5
×
 

Perl dynamic-features

on

  • 3,075 views

 

Statistics

Views

Total Views
3,075
Views on SlideShare
3,055
Embed Views
20

Actions

Likes
0
Downloads
12
Comments
1

3 Embeds 20

http://allframeworks.ru 17
http://www.allframeworks.ru 2
http://www.slideshare.net 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Perl dynamic-features Perl dynamic-features Presentation Transcript

  • Динамические возможности языка 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