39
Динамические возможности языка Perl Есть ли что-то, чего нельзя сделать в Perl? Валерий Студенников, [email protected] May 2010 Динамические возможности языка Perl 1/39

Perl dynamic-features

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Perl dynamic-features

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

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

Валерий Студенников,[email protected]

May 2010

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

Page 2: Perl dynamic-features

История доклада

Ключевые преимуществаКлючевые преимуществаКлючевые преимуществаКлючевые преимущества

Скоростьразработки

Объём кода

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

Page 3: Perl dynamic-features

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

Динамический язык позволяет менять код / структурупрограммы во время выполнения;

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

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

Page 4: Perl dynamic-features

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

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

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

Page 5: Perl dynamic-features

Символические ссылки${ $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

Page 6: Perl dynamic-features

Как избежать предупреждений

${ ’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

Page 7: Perl dynamic-features

Обращение к переменной по имени

$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

Page 8: Perl dynamic-features

Присваивание переменным на лету

our $myname = 1 ;$varname = ’myname ’ ;

Опять используем символически ссылки:

${$varname} = 123 ;${__PACKAGE__. ’ : : ’ . $varname} = 123 ;

Опять же через eval:

eval “ \ $$varname = 123 ” ;

Про typeglob всё-таки попозже...

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

Page 9: Perl dynamic-features

Typeglobs

Typeglobs...

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

Page 10: Perl dynamic-features

TypeglobsОбщее понятие

package MyPkg ;

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

say ∗abc ;say ∗MyPkg : : abc ;

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

Page 11: Perl dynamic-features

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

Page 12: Perl dynamic-features

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

Page 13: Perl dynamic-features

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

Page 14: Perl dynamic-features

Просмотр содержимого 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

Page 15: Perl dynamic-features

Просмотр содержимого 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

Page 16: Perl dynamic-features

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

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

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

Page 17: Perl dynamic-features

Вызов функции / метода по имени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

Page 18: Perl dynamic-features

Вызов функции из неизвестного пакетаИмя функции известно заранее:

$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

Page 19: Perl dynamic-features

Получить ссылку на функцию

$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

Page 20: Perl dynamic-features

Вызов функции по ссылке

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

$ r e f−>( @args ) ;

&$ r e f ( @args ) ;

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

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

Page 21: Perl dynamic-features

Запись функции в пространство имён$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

Page 22: Perl dynamic-features

Способы переопределения функции∗{"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

Page 23: Perl dynamic-features

Замыкания

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

Page 24: Perl dynamic-features

ЗамыканияИспользование для accessors

sub _get {my ( $ s e l f , $ f ldname ) = @_;. . .

}

$obj−>_get ( ’ username ’ ) ;

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

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

Page 25: Perl dynamic-features

ЗамыканияПример применения замыканий: 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

Page 26: Perl dynamic-features

Выполнение произвольного кода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

Page 27: Perl dynamic-features

Выполнение кода из файлаЗагрузить и выполнить содержимое файла: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

Page 28: Perl dynamic-features

%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

Page 29: Perl dynamic-features

@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

Page 30: Perl dynamic-features

Подгрузка модулей на лету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

Page 31: Perl dynamic-features

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

Page 32: Perl dynamic-features

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

Page 33: Perl dynamic-features

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

Page 34: Perl dynamic-features

Devel::DeclareОпределение новых ключевых слов / синтаксическихконструкций.Например:

method foo ( $arg1 , $arg2 ) {. . .

}

=⇒sub f oo {

my ( $ s e l f , $arg1 , $arg2 ) = @_;. . .

}

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

Page 35: Perl dynamic-features

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

Page 36: Perl dynamic-features

Демонстрация возможностей 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

Page 37: Perl dynamic-features

Демонстрация возможностей 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

Page 38: Perl dynamic-features

Что почитать

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

Page 39: Perl dynamic-features

КонецЪ

use Pe r l o r die ;

use LATEX2ε;

Вопросы?

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