- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования Perl - Михаил Шохирев
Шрифт:
Интервал:
Закладка:
Другая форма обращения к подпрограмме с использованием ссылочной переменной предполагает использование префикса &:
$max_of_list = &$ref2max(@list_of_numbers); # можно окружить ссылочную переменную фигурными скобками $max_of_list = &{$ref2max}(@list_of_numbers);
Вызов подпрограммы без параметров в этом случае можно записывать без круглых скобок, а при использовании -> скобки обязательны (иначе как узнать, что это обращение к подпрограмме?):
&$reference_to_procedure; # с префиксом подпрограмм $reference_to_procedure->(); # с операцией разыменования
Если предполагается, что доступ к подпрограмме будет происходить не по имени, а только по ссылке, то можно определить анонимную подпрограмму и присвоить ссылку на нее в скалярную переменную, через которую будет осуществляться вызов подпрограммы.
my $ref2sum = sub { # определение анонимной подпрограммы my $sum = 0; # вычисляет сумму списка значений $sum += $_ foreach (@_); return $sum; }; # конец операции присваивания переменной $ref2sum print $ref2sum->(1..5), " n";
Ссылки на подпрограммы бывает удобно хранить в массивах, например, когда над одними и теми же данными нужно выполнить целый список преобразований. Примерно так:
my @refs = ($ref2read, $ref2calc, $ref2format); for (my $i = 0; $i < @refs; $i++) { @data = $refs[$i]->(@data); # обработать данные }
В других случаях ссылки на подпрограммы предпочтительнее поместить в хэш, чтобы в каждом его элементе подпрограмма ассоциировалась с нужным поисковым ключом. Как в этом примере:
my %refs2subs = ('SUM' => $ref2sum, 'MAX' => $ref2max); print $refs2subs{'SUM'}->(1..3), " n";
В Perl переменные по умолчанию видимы в пределах всей программы (точнее, в пределах пакета, но об этом будет рассказано позднее). Практика доказала, что использование глобальных переменных противоречит принципу модульности, поскольку связывает части программы зависимостями от глобальных данных. Поэтому во всех языках программирования предусмотрены средства ограничения видимости переменных. Как уже упоминалось в лекции 2, в Perl это делается с помощью объявления переменных. Чтобы ограничить видимость переменных рамками блока или подпрограммы, нужно объявить для них лексическую область видимости с помощью функции my(), как это уже делалось в приводимых ранее примерах. Когда при помощи my объявляется несколько переменных, то все они должны заключаться в круглые скобки, как показано ниже:
my ($var1, $var2, $var3) = (1, 2, 3); # правильно # запись my ($var1=1, $var2=2, $var3=3) ошибочна my $var4 = 4, $var5 = 5; # $var5 - глобальная, а не my
Чтобы проследить, как изменяются значения переменных, объявленных в главной программе и подпрограммах, внимательно прочитайте следующий пример (скучный, но полезный для понимания):
use strict; my $var = 'm'; # лексическая $var в main print "1(main)='$var'n"; # выведет: 1(main)='m' sub1(); print "7(main):'$var'n"; # выведет: 7(main):'z' sub sub1 { print "2(sub1)='$var'"; $var = 's'; # изменяется $var из main! print "-->'$var'n"; # выведет: 2(sub1)='m'-->'s' my $var = '1'; # изменена $var из sub1 print "3(sub1)='$var'n"; # выведет: 3(sub1)='1' sub2(); # снова видима $var1 из sub1 print "6(sub1):'$var'n"; # выведет: 6(sub1):'1' } sub sub2 { # снова видима $var из main print "4(sub2):'$var'"; $var = 'z'; # изменяется $var из main!! print "-->'$var'n"; # выведет: 4(sub2):'s'-->'z' my $var = '2'; # изменена $var1 из sub2 print "5(sub2)='$var'n"; # выведет: 5(sub2)='2' }
Обратите внимание, что лексическая переменная $var, объявленная в главной программе, видима в обеих подпрограммах sub1 и sub2, поскольку они статически объявлены в рамках той же программы. Но при выполнении программы в подпрограмме sub2 не видима переменная $var, объявленная в процедуре sub1. Из приведенного примера видно, что после объявления в подпрограмме лексических переменных с помощью my(), изменения этих переменных не затрагивают других переменных с теми же именами. Поэтому, чтобы избежать нежелательного изменения значений переменных в других частях программы, рекомендуется всегда объявлять для переменных лексическую область видимости. Проконтролировать наличие объявлений для переменных в программе поможет прагма use strict. Другая разновидность лексических переменных, описываемых с помощью функции our, будет рассмотрена в следующей лекции.
В Perl имеется функция local(), также влияющая на область видимости переменных. Многие считают, что более удачным названием для нее было бы save(), потому что ее основное назначение - скрыть текущее значение глобальных переменных. Эта функция не создает локальных переменных, а делает "локальными" значения существующих глобальных переменных в текущей подпрограмме, блоке, eval или программном файле. Это значит, что после выполнения local текущие значения указанных переменных сохраняются в скрытом стеке, и новые значения переменных будут видимы вплоть до выхода из выполняемой подпрограммы, блока или файла, после чего восстанавливаются сохраненные значения переменных. На время действия local переменные остаются глобальными, поэтому новые временные значения переменных будут видимы и в вызываемых подпрограммах. Из-за временного характера действия функции local иногда говорят, что она описывает динамическую область видимости. Несколько переменных, чьи значения делаются временно скрытыми при помощи local, должны заключаться в круглые скобки, как показано ниже:
local $_; # временно скрыть значение буферной переменной local ($global1, $equant) = (1, 2); # правильно
Посмотрите, как изменится результат, если переписать предыдущий пример с использованием local вместо my в подпрограмме sub1:
$var = 'm'; # ГЛОБАЛЬНУЮ $var можно скрыть через local print "1[main]='$var'n"; # выведет: 1[main]='m' sub1(); print "7[main]:'$var'n"; # выведет: 7[main]:'s' sub sub1 { print "2[sub1]='$var'"; $var = 's'; # изменена $var из main! print "-->'$var'n"; # выведет: 2[sub1]='m'-->'s' local $var = '1'; # значение ГЛОБАЛЬНОЙ $var скрывается print "3[sub1]#'$var'n"; # выведет: 3[sub1]#'1' sub2(); print "6[sub1]:'$var'n"; # выведет: 6[sub1]:'1' } sub sub2 { # видна ГЛОБАЛЬНАЯ $var из sub1 print "4[sub2]:'$var'"; $var = 'z'; # изменена $var из sub1! print "-->'$var'n"; # выведет: 4[sub2]:'1'-->'z' my $var = '2'; # изменена $var из sub2 print "5[sub2]='$var'n"; # выведет: 5[sub2]='2' }
Сравнивая эту программу с предыдущим примером, можно отметить следующие отличия.
1Переменную $var в главной программе пришлось сделать глобальной, так как local не может скрывать лексические переменные.
2Действие local распространяется до конца подпрограммы sub1, а также на вызываемую подпрограмму sub2.
3При выходе из подпрограммы sub1 действие local заканчивается и восстанавливается значение, которое содержала глобальная переменная $var до применения к ней local.
В современных программах в основном используют функцию my для задания переменным лексической области видимости. Оправданное применение функции local в Perl обычно сводится к следующим случаям:
1Временное скрытие значения глобальных переменных, в том числе у специальных переменных.
2Временная модификация отдельных элементов массивов и хэшей, даже имеющих лексическую область видимости.
3Создание локальных файловых манипуляторов в версиях Perl до 5.6, не поддерживающих использование лексических переменных для хранения файловых манипуляторов.
С помощью ссылок, подпрограмм и лексических переменных создаются очень интересные информационные объекты, называемые замыканиями (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

