Статические приватные переменные

Переменные, объявленные с ключевым словом my, являются приватными для пользовательской функции; при каждом последующем вызове они определяются заново. С ключевым словом state область видимости приватных переменных поQпрежнему ограничивается пользовательской функцией, но Perl сохраняет их значения между вызовами. Вернемся к первому примеру этой главы – в нем определялась функция marine, которая увеличивала значение переменной:

sub marine {
$n += 1; # Глобальная переменная $n
print "Hello, sailor number $n!\n";
}


Но вы уже знаете о директиве use strict, можете включить ее в программу… и понять, что теперь наше использование глобальной переменной $n стало невозможным. Переменную $n нельзя объявить лексической с ключевым словом my, потому что она не будет сохранять свое значение между вызовами. Проблема решается объявлением переменной с ключевым словом state. Такие переменные сохраняют свое значение между вызовами функции, а область их видимости ограничивается пользовательской функцией:

use 5.010;
sub marine {
state $n = 0; # private, persistent variable $n
$n += 1;
print "Hello, sailor number $n!\n";
}


Новая версия функция выдает тот же результат без использования глобальной переменной и без нарушения требований strict. При первом вызове функции Perl объявляет и инициализирует $n, а при всех последующих вызовах объявление игнорируется. Между вызовами Perl сохраняет текущее значение $n.

С ключевым словом state может быть объявлена переменная любого типа, не только скалярная. Следующая пользовательская функция запоминает свои аргументы и вычисляет накапливаемую сумму с применением массива state:

use 5.010;
running_sum( 5, 6 );
running_sum( 1..3 );
running_sum( 4 );
sub running_sum {
state $sum = 0;
state @numbers;
foreach my $number ( @_ ) {
push @numbers, $number;
$sum += $number;
}
say "The sum of (@numbers) is $sum";
}


При каждом вызове функция выводит новую сумму, прибавляя новые аргументы ко всем аргументам от предыдущих вызовов:

The sum of (5 6) is 11
The sum of (5 6 1 2 3) is 17
The sum of (5 6 1 2 3 4) is 21


Впрочем, для массивов и хешей устанавливается небольшое ограничение: в Perl 5.10 запрещена их инициализация в списочном контексте:

state @array = qw(a b c); # Ошибка!


Сообщение об ошибке наводит на мысль, что такая возможность появится в будущей версии Perl:

Initialization of state variables in list context currently forbidden ...
Теги:
функции
Добавлено: 20 Июля 2018 08:11:22 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...