Сравним две подпрограммы, которые можно использовать для вычисления первых N чисел Фибоначчи.
sub fibonacci1 {
my $n = shift;
my $i = 2;
my ($current, $previous, $preprevious) = (1,1);
return 1 if $n <= 2;
for ( ; $i < $n; $i++) {
$preprevious = $previous;
$previous = $current:
$current = $previous + $preprevious;
}
return $current;
}
sub fibonacci2 {
my ($previous, $preprevious) = (1,1);
my $current;
return sub {
my $n = shift;
return 1 if $n <= 2;
$current = $previous + $preprevious;
$preprevious = $previous;
$previous = $current;
}
}
С использованием функции fibonacci1 для вычисления первых $N чисел Фибоначчи можно использовать
следующий цикл:
$N = 15;
for $n (1..$N) {
print "f($n) = ", fibonacci1($n), "\n";
}
С использованием функции fibonacci2 то же самое можно сделать при помощи следующей
последовательности операторов:
$f = fibonacci2( );
for $n (l..$N){
print "f($n) = ", &$f($n), "\n";
}
Функция fibonacci1(n) вычисляет n-oe число Фибоначчи f(n). Для вычисления n-ого числа Фибоначи
надо выполнить n-2 операции сложения, где n >= 3. Таким образом, при использовании функции fibonacci1
для вычисления N первых чисел Фибоначчи необходимо выполнить всего
1 + 2 + ... + N-2 = (N-1)(N-2) / 2
операций сложения.
Функция fibonacci2 возвращает ссылку на анонимную функцию, которая всегда вычисляет только одно,
следующее число Фибоначчи на основании двух предыдущих, сохраненных в лексических переменных
$previous и $preprevious. Всего для вычисления N первых чисел Фибоначчи с использованием функции
fibonacci 2 требуется N-2 операции сложения.
Функция local( )
Функция lосal( ) также используется для объявления и инициализации переменных:
local EXPR;
local ($myvar, @mylist, $myhash);
local $pi = 3.14159;
local ($pi, $exp) = (3.14159, 2.71828);
Но в отличие от функции my( ), она создает не локальные переменные, а временные значения для
глобальных переменных внутри: подпрограммы; заключенного в фигурные скобки блока операторов; выражения,
переданного на выполнение функции eval( ) или файла, в зависимости от того, в каком месте вызвана для
объявления переменных сама функция local( ). Если функция local( ) применяется для описания нескольких
переменных, они должны быть заключены в скобки. Если глобальная переменная, объявленная при помощи
функции local( ), ранее встречалась до этого объявления и имела некоторое значение, то это значение
сохраняется в скрытом стеке и восстанавливается после выхода соответственно из подпрограммы, блока,
функции eval( ) или файла. Переменная, объявленная при помощи функции local( ), или, точнее, ее
временное значение, доступно для любой функции, вызванной внутри подпрограммы, блока, функции eval( )
или файла, в которых сделано объявление. Такую переменную называют динамической, а ее область
видимости — динамической областью видимости, отражая в названии тот факт, что область видимости
переменной динамически изменяется с каждым вызовом функции, получающей доступ к этой переменной.
Функция my( ) является более новой, она появилась в версии Perl 5.0. Для создания действительно
локальных переменных рекомендуется использовать именно функцию my( ), а не функцию local( ).
Впрочем, есть несколько случаев, когда функция my( ) не может заменить функцию local( ).