Глава 8: Функции.
8.5 Локальные переменные в функциях
Мы уже говорили о переменной @_ и о том, как для каждой подпрограммы, вызываемой с параметрами, создается локальная копия этой переменной. Вы можете создавать собственные скалярные переменные, переменные-массивы и хеш-переменные, которые будут работать точно так же. Это делается с помощью операции ту, которая получает список имен переменных и создает их локальные версии (или реализации, если вам так больше нравятся). Вот снова функция add, на этот раз построенная на основе операции ту:
sub add {
mу ($sum); # сделать $sum локальной переменной
$sum =0; # инициализировать сумму
foreach $_ (@_) {
$sum += $ ; # прибавить все элементы
}
return $sum # последнее вычисленное выражение: сумма всех элементов
}
Когда выполняется первый оператор в теле подпрограммы, текущее значение глобальной переменной $sum сохраняется и создается совершенно новая переменная с именем $sum (и значением undef). При выходе из подпрограммы Perl отбрасывает эту локальную переменную и восстанавливает предыдущее (глобальное) значение. Эта схема работает даже в том случае, если переменная $sum в текущий момент является локальной переменной, взятой из другой подпрограммы (той, которая вызывает данную подпрограмму, или той, которая вызывает ту, которая вызывает данную подпрограмму, и т.д.). Переменные могут иметь много вложенных локальных версий, но одновременно разрешается обращаться только к одной из них.
Вот способ создания списка всех элементов массива, значения которых превышают число 100:
sub bigger_than_100 {
my (Oresult); # временная для хранения возвращаемого значения
foreach $_ (@_) { # проход по списку аргументов
if ($_ > 100) { # подходит?
push(@result,$_); # прибавить
}
}
return @result; # возвратить окончательный список
}
Что, если бы нам понадобились все элементы, значения которых превышают 50, а не 100? Пришлось бы отредактировать программу, заменив 100 на 50. А если бы нам было нужно и то, и другое? В этом случае следовало бы заменить 50 или 100 ссылкой на переменную. Тогда программа выглядела бы так:
sub bigger_than {
my($n,@values); # создать локальные переменные
($n,@values) = @_; # выделить из списка аргументов значение предела
# и элементы массива
my (@result); # временная переменная для хранения возвращаемого 4 значения
foreach $_ (@values) { # проход по списку аргументов
if ($_ > $n) { # подходит?
push(@result,$_); # прибавить
}
}
@result; # возвратить окончательный список
}
# примеры вызова:
@new = bigger_than(100,@list); # @new содержит все значения
@list > 100 @this = bigger_than(5,l,5,15,30); # @this содержит значение (15,30)
Обратите внимание: в этот раз мы использовали еще две локальные переменные, чтобы присвоить имена аргументам. Это — весьма распространенная практика, потому что гораздо удобнее (да и безопаснее) использовать переменные $n и $values, чем указывать $_[0] и @_[1. .$#_].
В результате выполнения операции my создается список, который можно использовать в левой части операции присваивания. Этому списку можно присваивать начальные значения для каждой из вновь созданных переменных. (Если значения списку не присвоить, то новые переменные вначале получат значение undef, как и любая другая переменная.) Это значит, что мы можем объединить первые два оператора этой подпрограммы, т.е. операторы
my($n,@values);
($n,@values) = @_; # выделить из списка аргументов значение предела
# и элементы массива заменить на
my($n,@values)= @_;
Этот прием очень распространен в Perl. Локальным переменным, не являющимся аргументами, можно таким же способом присваивать литеральные значения, например:
my($sum) = 0; # инициализировать локальную переменную
Имейте в виду, что, несмотря на наличие объявления, my в действительности представляет собой выполняемую операцию. Стратегия правильной работы в Perl состоит в том, что все операции my должны быть размещены в начале определения подпрограммы, до того, как начинается реализация основных выполняемых в ней действий.
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|