Date post: | 18-Nov-2014 |
Category: |
Technology |
Upload: | valeriy-studennikov |
View: | 3,174 times |
Download: | 0 times |
Динамические возможности языкаPerl
Есть ли что-то, чего нельзя сделать в Perl?
Валерий Студенников,[email protected]
May 2010
Динамические возможности языка Perl 1/39
История доклада
Ключевые преимуществаКлючевые преимуществаКлючевые преимуществаКлючевые преимущества
Скоростьразработки
Объём кода
More Fun
Форусировка на задаче 2
задачи, а не на языкерешения
ДинамическаяДинамическаяДинамическаяДинамическаятипизациятипизациятипизациятипизация
Тестирование противстатичной типизации
5000 модулей на CPANсвязанных с тестированием
Готовые библиотекиГотовые библиотекиГотовые библиотекиГотовые библиотекиCPAN
80000 модулей
20000 дистрибутивов
Охвачены все сферы примения
ДинамическиеДинамическиеДинамическиеДинамическиевозможностивозможностивозможностивозможности
Например...
Замыкания
Компиляция "на лету"Создание модулей, классов,функций, переменных runtime
Операции с symbol table
Devel::Declare -- созданиедополнительных синтаксическихконструкций
В результатеMechanism, not policy
можно делать ВСЁНапример свой ООMoose
Например, продвинутыйшаблонизатор (TT)
Доп. преимуществаДоп. преимуществаДоп. преимуществаДоп. преимущества
Подходит для любых задач
Кроме вычислительных
Прекрасно подходит для webFull-stack
Подходит для бизнес-логики
Один язык для всего
Web-приложения
Сетевые демоны
CRON-скрипты
Кросс-платформенность изкоробки
Прекрасная поддержка unicode
Великолепно "Масштабируется"Идеален для oneliners
Подходит для больших проектов
Встроенные структурыВстроенные структурыВстроенные структурыВстроенные структурыданныхданныхданныхданных
Очень просто обращаться
Прозрачная конвертацияв/из JSON, YAML
Не нужны доп. библиотеки Возможность писать на "голом" Perl
ПроизводительностьПроизводительностьПроизводительностьПроизводительностьДостаточная
По крайней мере для бизнеслогики и web -- более чем
Критичные участки можнописать на C/C++ (XS) XS сложен Inline прост
ВысокоуровневыеВысокоуровневыеВысокоуровневыеВысокоуровневыевозможностивозможностивозможностивозможности
Операции над списками
Цепочные конструкции
Regexps
МультипарадигменностьМультипарадигменностьМультипарадигменностьМультипарадигменность
ФП "Higher Order Perl"
ООПООП можно делать "подсебя" какое угодно
Процедурное
"Бесструктурное"
More FunMore FunMore FunMore Fun
TIMTOWTDI "Mechanism not policy"
"Насыщенный" код
Perl hackers
Адекватное коммьюнити
DWIM
Obfuscations
Крупные проектыКрупные проектыКрупные проектыКрупные проекты
Yandex
Rambler
LiveJournal
Mail.ru
Регистраторы доменов
Rucenter
Reg.ru
Webnames
Masterhost
Мало новых больших/успешных проектовпублично анонсирующих использованиеperl НедостаткиНедостаткиНедостаткиНедостатки
Кривая обучения
Много "исторического мусора"Punctiation variables
Formats
Сопровождабельность кодаТребует самодисциплины иквалификации
Не очень удачнаямультитредовость
Зато прекрасная работа сасинхронным IO
POE
IO::Lambda
Coro
AnyEvent
IO::AIO
Любую фичу можнорассматривать как недостаток;)
Неудобный поиск модулей наCPAN (их СЛИШКОМ много)
Бывает, трудно найти САМОЕподходящее решениеЧасть модулей устарела, необновляется
Отсутствие удобоваримгодешёвого хостинга Однако, есть VPS...Не так удобно выкладыватьна хостинг, как PHP
Дополнительно повышает"планку входа"
Большое количествоинформации о моральноустаревших подходах CGI.pm...
Замечания по докладуЗамечания по докладуЗамечания по докладуЗамечания по докладу
ЛЮБУЮ фичу можно рассматриватькак преимущество, так и какнедостаток
Невозможно быть 100%объективным, весь мирIT-технологий субъективен
Не хочу разводить holywar
Каждый использует то, чтоему ближе
Хочу донести некоторыесоображения, которые можнопринять или не принимать
Ресурсы по темеРесурсы по темеРесурсы по темеРесурсы по темеhttp://123.writeboard.com/470b8ce9d41307670
http://www.slideshare.net/aspushkin/perl-vs-java
http://www.perl.com/pub/a/1999/03/pm.html
"Преимущества Perl""Преимущества Perl""Преимущества Perl""Преимущества Perl" 1
Динамические возможности языка 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 hou l d b u i l d & run okour $ f r e d ;$b = " f r e d " ;$a = $$b ;$c = ${" de f " } ;$c = @{" de f " } ;$c = %{" de f " } ;$c = ∗{" de f " } ;$c = \&{" de f " } ;
Динамические возможности языка Perl 5/39
Как избежать предупреждений
${ ’XXX ’ } = 123 ;
Получаем:«Can’t use string ("XXX") as a SCALAR refwhile "strict refs" in use at - line YYY»
# Боремся так :{
no s t r i c t ’ r e f s ’ ;# Здесь делаем грязные дела. . .
}
Динамические возможности языка Perl 6/39
Обращение к переменной по имени
$va r = 123 ; @var = ( 1 ) ; %va r = (1 , 2 ) ;$name = ’ va r ’ ;
Обратимся через символически ссылки:
print ${$name} , @{$name} , %{$name } ;print ${__PACKAGE__. ’ : : ’ . $name } ;
Ну и докучи через eval:
print eval ’ $name ’ ;
А можно ешё через typeglob, но об это позже...
Динамические возможности языка Perl 7/39
Присваивание переменным на лету
our $myname = 1 ;$varname = ’myname ’ ;
Опять используем символически ссылки:
${$varname} = 123 ;${__PACKAGE__. ’ : : ’ . $varname} = 123 ;
Опять же через 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 ; }
say ∗abc ;say ∗MyPkg : : abc ;
Динамические возможности языка Perl 10/39
TypeglobsTypeglobs как lvalue
SYNOPSIS:
∗ t h i s = ∗ t ha t ;∗ f oo = ∗STDOUT;
∗ f oo = \ $bar ;∗ f oo = \@bar ;∗ f oo = \%bar ;∗ f oo = \&bar ;
local ∗Here : : b l u e = \$There : : g r een ;
Динамические возможности языка Perl 11/39
TypeglobsВсе способы получить доступ к значению typeglob
package A;our $a = 123 ;
say ${ ∗a } ;say ${ ∗A : : a } ;say ${ ∗{A : : a} } ;say ${ ∗{ ’A : : a ’ } } ;say ${ ∗{ ’A : : a ’ }{SCALAR} } ;say ${ ${∗A: : } { a} } ;
our @a = (1 , 2 , 3 ) ;say @{ ∗a } ;
do_that ( ∗STDOUT ) ;do_that ( \∗STDOUT ) ;
Динамические возможности языка Perl 12/39
TypeglobsПрисваивание, локализация
$spud = "Wow! " ;@spud = ( " idaho " , " r u s s e t " ) ;
Алиасим «potato» −→ «spud» через typeglob:∗ pota to = ∗ spud ;say $pota to ; # p r i n t s "Wow!"say @potato ; # p r i n t s " idaho r u s s e t "
Инкремент $a неявно через typeglob и ссылку:$a = 10 ;∗b = ∗a ; $b++ ;$r = \$a ; $$r++;
Динамические возможности языка Perl 13/39
Просмотр содержимого namespace
package A;our @a = ( 1 , 2 , 3 ) ;sub two { 2 } ;
package main ;print Dumper(\%{∗{A : : } } ) ; # A : : t y p eg l ob
Prints:
$VAR1 = {’a’ => *A::a,’two’ => *A::two
};
Динамические возможности языка Perl 14/39
Просмотр содержимого namespace
Ключи хеша typeglob:
SCALAR скалярARRAY массивHASH хэшCODE функция
FORMAT форматGLOB ссылка на себя
IO файлхендл
PACKAGE названиепакета
NAME имя в таблицеимён
our @a = ( 1 , 2 , 3 ) ;print 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 ) ;
Вызов метода по имени:
$ob j e c t−>$subname ( 2 ) ;
Динамические возможности языка Perl 17/39
Вызов функции из неизвестного пакетаИмя функции известно заранее:
$package−>ac t i o n ( ) ;
Имя функции заранее не известно:
$ f u l l n ame = $package . ’ : : ’ . $subname ;$subname = ’ s q r ’ ;$ fu l l name−>( @args ) ;&$ fu l l n ame ( @args ) ;∗{ $ f u l l n ame}−>( @args ) ;&{ ∗{ $ f u l l n ame } }( @args ) ;
Ещё один синтаксис1:
$package−>$subname ( @args ) ;
1Внимание, первым аргументом будет передано название пакета!Динамические возможности языка Perl 18/39
Получить ссылку на функцию
$packagename = ’MyPackage ’ ;$subname = ’ sq 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} = \&sq r ;a l i a s ( 4 ) ;
Записываем в namespace произвольного пакета:∗{"${packagname } : : $subname"} = $cod e r e f ;$packagname−>a l i a s ( 2 ) ;
Переопределяем стандартные функции:∗system = \&mysub ;∗die = ∗CORE : : die ;∗CORE : : GLOBAL : : die = sub {
warn "You t r i e d to d i e w i th ’@_’ "} ;
Динамические возможности языка Perl 21/39
Способы переопределения функции∗{"A : : t e s t "} = $cod e r e f ;
package A;sub t e s t { 1 } ;package B;sub A : : t e s t { 2 } ;pr int 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;pr int 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 = sh i f t ;
sub i nner_sub {print $ v a r i a b l e ;
}}
Динамические возможности языка Perl 23/39
ЗамыканияИспользование для accessors
sub _get {my ( $ s e l f , $ f ldname ) = @_;. . .
}
$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 { # Обёртка для _getmy $ 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 ub r e f ;}__PACKAGE__−>make_ro_accessor ( ’ username ’ )
pr int $obj−>get_username ;
Динамические возможности языка Perl 25/39
Выполнение произвольного кодаeval {} используется для отлова исключений:
eval { d o s t u f f ( ) } ;i f ($@) { compla in ( ) }
eval "" выполняет произвольный код:
eval " p r i n t 123" ;
Не нужно злоупотреблять!
Пример — создадим функцию на лету:
eval ’ sub sq r { $_ [ 0 ] ∗ $_ [ 0 ] } ’ ;print s q r ( 2 ) ;
Динамические возможности языка Perl 26/39
Выполнение кода из файлаЗагрузить и выполнить содержимое файла:do $ f i l e n ame ;
Эквивалент "do":eval ‘ c a t $ f i l ename ‘
Так можно сделать простейшие конфиги(хотя это и не рекомендуемая практика):$ c o n f i g = (
dbname => ’ t e s t ’ ,username => ’ t e s t ’ ,pa s s => ’ s d s f d f ’
) ;Динамические возможности языка Perl 27/39
%INCp e r l −MData : : Dumper −e ’ p r i n t Dumper ( \%INC ) ’
$VAR1 = {’warnings/register.pm’ => ’/usr/lib/perl5/5.10.0/warnings/register.pm’,’bytes.pm’ => ’/usr/lib/perl5/5.10.0/bytes.pm’,’XSLoader.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-thread-multi/XSLoader.pm’,’Data/Dumper.pm’ => ’/usr/lib/perl5/5.10.0/i386-linux-thread-multi/Data/Dumper.pm’...
};
p e r l −MCGI −e ’ p r i n t j o i n "\n" , s o r t key s %INC ’
CGI.pmCGI/Util.pmCarp.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-multi/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 ame ;
Безопасная одноразовая загрузка модулей:sub use_once ( $ ) {
my ( $module ) = @_;
my $ f i l e n ame = $module . ’ . pm ’ ;$ f i l e n ame =~ s / : : / \// xmsg ;
unless ( $INC{ $ f i l e n ame }) {eval { require $ f i l e n ame } or return ;import $module ;
}return 1 ;
}
Динамические возможности языка Perl 30/39
AUTOLOADПример 1
sub AUTOLOAD{
our $AUTOLOAD;
return " I s e e $AUTOLOAD(@_)\n" ;}
print b l a r g ( 1 2 3 ) ;# p r i n t s «I s e e main : : b l a r g (123)»
Динамические возможности языка Perl 31/39
AUTOLOADПример 2
sub AUTOLOAD {my $package = s h i f t @_;my $name = our $AUTOLOAD;
∗$AUTOLOAD = sub { pr int " I s e e $name (@_)\n" } ;goto &$AUTOLOAD; # Re s t a r t the new r o u t i n e
}
b l a r g ( 3 0 ) ; # p r i n t s : I s e e main : : b l a r g (30)g l a r b ( 4 0 ) ; # p r i n t s : I s e e main : : g l a r b (40)b l a r g ( 5 0 ) ; # p r i n t s : I s e e main : : b l a r g (50)
Динамические возможности языка 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 $ f1 = ’ 1/2 ’ ;print $ f1 + ‘1 /3 ’ ; # p r i n t s ’5/6 ’
Динамические возможности языка Perl 33/39
Devel::DeclareОпределение новых ключевых слов / синтаксическихконструкций.Например:
method foo ( $arg1 , $arg2 ) {. . .
}
=⇒sub f oo {
my ( $ s e l f , $arg1 , $arg2 ) = @_;. . .
}
Динамические возможности языка Perl 34/39
PadWalker
PadWalker — play with other peoples’ lexical variables
peek_my LEVELpeek_our LEVELpeek_sub SUBc lo s ed_ove r SUBset_c lo sed_ove r SUB, HASH_REFvar_name LEVEL , VAR_REFvar_name SUB, VAR_REF
Динамические возможности языка Perl 35/39
Демонстрация возможностей PerlBarely Legal XXX Perl
Jos Boumans «Barely Legal XXX Perl»:Acme::BadExampleCorrect SyntaxImpossible to runTries to do very nasty things!
p e r l −MAnti : : Code \−e ’ use Acme : : BadExample ; warn "done" ’
Выполняется до конца, в конце выводит "done".Код возврата — 0.
Динамические возможности языка Perl 36/39
Демонстрация возможностей PerlBarely Legal XXX Perl
package Ant i : : Code ;BEGIN {
# stop comp i l e e r r o r s$INC{ ’ s t r i c t .pm ’ } = 1 ;$INC{ ’ warn ing s .pm ’ } = 1 ;# load dummy f i l e s t ha t do no harmr e q u i r e l e s s ;u n s h i f t @INC , sub {
i f ( c a l l e r eq ’Acme : : BadExample ’ ) {open my $fh , $INC{ ’ l e s s .pm ’ }
or r e t u r n ;r e t u r n $fh ;
}r e t u r n ;
} ;# stop system c a l l s∗CORE : : GLOBAL : : sy s tem = sub { 0 } ;# Never l e t i t d i e
∗CORE : : GLOBAL : : d i e = sub {warn "You t r i e d to d i e w i th ’@_’ "
} ;# fake our supe r c l a s s∗SUPER : : new = sub { {} } ;# de f i n e a sub tha t i s used as a FH∗Acme : : BadExample : : FOO = sub { l a s t } ;# f o r c e a ‘ t r u e ’ v a l u e at end o f f i l esub l e s s : : impo r t {
use o v e r l o a d ;o v e r l o a d : : c on s t an t (
q => sub { $_ [ 1 ] | | 1 }) ;
}}1 ;
Динамические возможности языка 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 Tablesand Typeglobs»
Оригинал презентации:https://svn.reg.ru/oss/presentation/devconf-2010/
Динамические возможности языка Perl 38/39
КонецЪ
use Pe r l o r die ;
use LATEX2ε;
Вопросы?
Динамические возможности языка Perl 39/39