Чтение онлайн

на главную

Жанры

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

Шохирев Михаил Васильевич

Шрифт:

$max_of_list = $ref2max->(@list_of_numbers);

Другая форма обращения к подпрограмме с использованием ссылочной переменной предполагает использование префикса &:

$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, должны заключаться в круглые скобки, как показано ниже:

Поделиться:
Популярные книги

Ученичество. Книга 1

Понарошку Евгений
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ученичество. Книга 1

Матабар III

Клеванский Кирилл Сергеевич
3. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар III

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Вопреки судьбе, или В другой мир за счастьем

Цвик Катерина Александровна
Любовные романы:
любовно-фантастические романы
6.46
рейтинг книги
Вопреки судьбе, или В другой мир за счастьем

Идеальный мир для Лекаря 23

Сапфир Олег
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 23

Довлатов. Сонный лекарь

Голд Джон
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь

Мама из другого мира. Дела семейные и не только

Рыжая Ехидна
4. Королевский приют имени графа Тадеуса Оберона
Любовные романы:
любовно-фантастические романы
9.34
рейтинг книги
Мама из другого мира. Дела семейные и не только

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Треск штанов

Ланцов Михаил Алексеевич
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Треск штанов

Лучший из худших

Дашко Дмитрий
1. Лучший из худших
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Лучший из худших

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Гром над Академией Часть 3

Машуков Тимур
4. Гром над миром
Фантастика:
фэнтези
5.25
рейтинг книги
Гром над Академией Часть 3

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3