Язык программирования Perl

Замыкания


С помощью ссылок, подпрограмм и лексических переменных создаются очень интересные информационные объекты, называемые замыканиями (closure). Они основаны на известном принципе, что объект ссылки сохраняется до тех пор, пока на него указывает хотя бы одна ссылка. А переменная может хранить ссылку на значение лексической переменной, динамически создаваемой при входе в блок и автоматически уничтожаемой при выходе из него. Это видно из следующего примера:

my $ref; # переменная для хранения ссылки { # в блоке создается my $lex_var = 'Суслик'; # переменная $lex_var $ref = \$lex_var; # в $ref помещена } # ссылка на переменную # $lex_var освобождается при выходе из блока print "Ты суслика видишь? И я не вижу. А он есть: "; print ${$ref}; # объект ссылки доступен через $ref

Подобным образом можно хранить ссылку на анонимную подпрограмму, из которой будут доступны динамически созданные лексические переменные. Такая подпрограмма, вызванная по ссылке, будет иметь доступ к области видимости этих переменных. Приведем пример простого замыкания:

my $ref; # переменная для хранения ссылки { # в блоке создается my $lex_var = 'Верблюд'; # переменная $lex_var $ref = sub { return $lex_var }; # в $ref помещена } # ссылка на подпрограмму # $lex_var освобождается при выходе из блока print &$ref; # объект возвращается подпрограммой по $ref

Замыкания можно создавать динамически при выполнении программы. Приведем пример функции, которая при каждом вызове создает замыкание и возвращает ссылку на него. При этом каждый раз создается новый экземпляр лексической переменной, замкнутый от доступа извне:

sub make_closure { # функция создания замыканий: my ($animal) = @_; # В лексической переменной # сохраняется аргумент функции my $ref2closure = sub { # и ссылка на # анонимную подпрограмму, return $animal; # которая имеет доступ }; # к лексической переменной. return $ref2closure; # возвращает ссылку на подпрограмму } # создаем 2 замыкания, сохраняя в них разные значения: my $camel1 = make_closure('дромадер'); # одногорбый верблюд my $camel2 = make_closure('бактриан'); # двугорбый верблюд print &$camel1, ' ', $camel2->(); # доступ по ссылкам

В этой лекции изложены основные сведения о подпрограммах в Perl. Мы продолжим изучение подпрограмм в лекции 13, где будет рассказано о библиотечных модулях, и в лекции 14, посвященной объектному программированию на Perl. Конечно, осталось еще много нерассмотренных тонкостей, касающихся работы с подпрограммами, которые можно узнать из книг [43] и [55] или из стандартной документации, обратившись к старой доброй утилите

perldoc perlsub


В этой лекции изложены основные сведения о подпрограммах в Perl. Мы продолжим изучение подпрограмм в лекции 13, где будет рассказано о библиотечных модулях, и в лекции 14, посвященной объектному программированию на Perl. Конечно, осталось еще много нерассмотренных тонкостей, касающихся работы с подпрограммами, которые можно узнать из книг [43] и [55] или из стандартной документации, обратившись к старой доброй утилите

perldoc perlsub

© 2003-2007 INTUIT.ru. Все права защищены.

Содержание раздела