Perl dynamic-features

Post on 18-Nov-2014

3.174 views 0 download

description

 

Transcript of Perl dynamic-features

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

Есть ли что-то, чего нельзя сделать в Perl?

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

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