Создание закрытых переменных в функциях

Проблема

В подпрограмме потребовалось создать временную переменную. Использование глобальных переменных нежелательно, поскольку другие подпрограммы могут получить к ним доступ.

Решение

Воспользуйтесь ключевым словом my для объявления переменной, ограниченной некоторой областью программы:
sub somefunc {
  my $variable;                      # Переменная $variable невидима
                                     # за пределами somefunc()
  my ($another, @an_array, %a_hash); # Объявляем несколько
                                     # переменных сразу
  # ...
}

Комментарий

Оператор mу ограничивает использование переменной и обращение к ней определенным участком программы. За пределами этого участка переменная недоступна. Такой участок называется областью действия (scope).
Переменные, объявленные с ключевым словом my, обладают лексической областью действия — это означает, что они существуют лишь в границах некоторого фрагмента исходного текста. Например, областью действия переменной $variable из решения является функция somefunc, в которой она была определена. Переменная создается при вызове somefunc и уничтожается при ее завершении. Переменная доступна внутри функции, но не за ее пределами.
Лексическая область действия обычно представляет собой программный блок, заключенный в фигурные скобки, — например, определение тела подпрограммы somefunc или границы команд if, while, for, foreach и eval. Лексическая область действия также может представлять собой весь файл или строку, переданную eval. Поскольку лексическая область действия обычно является блоком, иногда мы говорим, что лексические переменные (переменные с лексической областью действия) видны только в своем блоке — имеется в виду, что они видны только в границах своей области действия.
Поскольку фрагменты программы, в которых видна переменная my, определяются во время компиляции и не изменяются позднее, лексическая область действия иногда не совсем точно называется «статической областью действия», противоположностью является динамическая область действия.
Объявление mу может сочетаться с присваиванием. При определении сразу нескольких переменных используются круглые скобки:
mу ($name, $age) = @ARGV;
mу $start = fetch_time();
Эти лексические переменные ведут себя как обычные локальные переменные. Вложенный блок видит лексические переменные, объявленные в родительских по отношению к нему блоках, но не в других, не связанных с ними блоках:
my ($a, $b) = @pair;
mу $с = fetch_time();
sub check_x {
  mу $х = $_[0];
  mу $у = "whatever";
  run_check();
  if ($condition) {
    print "got $x\n";
  }
}
В приведенном выше фрагменте блок if внутри функции может обращаться к закрытой переменной $х. Однако в функции run_check, вызванной из этой области, переменные $х и $у недоступны, потому что она предположительно определяется в другой области действия. Однако check_x может обращаться к $а, $b и $с из внешней области, поскольку определяется в одной области действия с этими переменными.
Именованные подпрограммы не следует объявлять внутри объявлений других именованных подпрограмм. Такие подпрограммы в отличие от полноценных замыканий не обеспечивают правильной привязки лексических переменных.
При выходе лексической переменной за пределы области действия занимаемая ею память освобождается, если на нее не существует ссылок как для массива @arguments в следующем фрагменте:
sub save_array {
  my @arguments = @_;
  push (@Global_Array, \@arguments);
}

См. также




2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: