Изучаем Perl

       

Локальные переменные в функциях


Мы уже говорили о переменной @_ и о том, как для каждой подпрограммы, вызываемой с параметрами, создается локальная копия этой переменной. Вы можете создавать собственные скалярные переменные, переменные-массивы и хеш-переменные, которые будут работать точно так же. Это делается с помощью операции ту, которая получает список имен переменных и создает их локальные версии (или реализации,

если вам так больше нравятся). Вот снова функция add, на этот раз построенная на основе операции ту:

sub add {

ту ($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 Oresult; # возвратить окончательный список }

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


sub bigger_than (

my($n,@values); # создать локальные переменные ($n,@values) = @_; # выделить из списка аргументов значение предела

# и элементы массива my (@result); # временная переменная для хранения возвращаемого

4 значения

foreach $_ (@values) ( # проход по списку аргументов if ($_ > $n) { # подходит?

push(Oresult,$_); # прибавить } )

@result; t возвратить окончательный список }

# примеры вызова:

@new = bigger_than(100,@list); # @new содержит все значения Olist > 100 @this " bigger_than(5,l,5,15,30); # @this содержит значение (15,30)

Обратите внимание: в этот раз мы использовали еще две локальные переменные, чтобы присвоить имена аргументам. Это — весьма распространенная практика, потому что гораздо удобнее (да и безопаснее) использовать переменные $п и $values, чем указывать $_[0] и @_[1. . $#_].

В результате выполнения операции my создается список, который можно использовать в левой части операции присваивания. Этому списку можно присваивать начальные значения для каждой из вновь созданных переменных. (Если значения списку не присвоить, то новые переменные вначале получат значение undef, как и любая другая переменная.) Это значит, что мы можем объединить первые два оператора этой подпрограммы, т.е. операторы

my($n,@values) ;

($n,@values) = @_; # выделить из списка аргументов значение предела # и элементы массива

заменить на

my($n,@values)= @_;

Этот прием очень распространен в Perl. Локальным переменным, не являющимся аргументами, можно таким же способом присваивать литеральные значения, например:

my($sum) = 0; # инициализировать локальную переменную

Имейте в виду, что, несмотря на наличие объявления, my в действительности представляет собой выполняемую операцию. Стратегия правильной работы в Perl состоит в том, что все операции my должны быть размещены в начале определения подпрограммы, до того, как начинается реализация основных выполняемых в ней действий.


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