Поиск

Область видимости

Из введения к этому занятию вы узнали, что подпрограммы позволяют сгруппировать фрагменты кода и дать им имена, которые затем можно использовать для вызова этих фрагментов кода из любого нужного места программы. Подпрограммы позволяют создать функционально законченные модули, решающие универсальные задачи. На основе переданных аргументов, встроенных функций и выражений подпрограмма возвращает определенное значение. Вы можете использовать эту подпрограмму в других программах, так как ее выполнение не зависит от окружающего контекста, — она просто берет аргументы, внутренние данные и на их основании вычисляет возвращаемое значение. Функция становится как бы "черным ящиком", который связывают с внешним миром только входные и выходные значения. Такие функции называются строгими.

А теперь давайте проанализируем два следующих фрагмента кода.

По большому счету, первая реализация функции намного лучше. Она не использует предустановленных внешних переменных. Вместо этого она копирует аргумент в переменную $veight и производит все вычисления с ней. Вторую реализацию трудно использовать в другой программе, для этого нужно, чтобы переменной $weight было присвоено соответствующее значение и обозначало то, что нам нужно. Если переменная с таким именем уже используется в других целях, вам придется изменить имя переменной, используемое в функции moonweight (), что не очень удобно.

Итак, первый вариант реализации лучше, но в нем по-прежнему чего-то не хватает. Переменная $weight может конфликтовать с другой переменной с подобным именем, если та встречается в программе.

Perl позволяет использовать одни и те же имена для обозначения различных переменных в большой программе. По умолчанию переменные Perl видимы в основной программе и в подпрограммах. Это так называемые глобальные переменные.

Допустим, вам нужно создать переменную, относящуюся только к данной функции. Для этого следует воспользоваться оператором my:

Внутри функции moonweight () переменная $weight является приватной переменной. Другие функции программы не имеют доступа к этой переменной. Таким образом, все другие переменные с именем $weight не пересекаются с переменной $weight функции moonweightf). Теперь подпрограмма совершенно изолирована от остальной части программы.

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

Оператор my можно использовать для объявления скаляров, массивов и хэшей, как приватных переменных подпрограммы. Дескрипторы файлов, подпрограммы и специальные переменные Perl ($!, $ , 8_ и др.) нельзя объявить приватными переменными. Можно объявлять сразу несколько переменных, поместив их имена в скобки:

Приватные переменные хранятся совсем не так, как глобальные. Глобальные и приватные переменные могут иметь одинаковые имена, но при этом не конфликтовать, как показано ниже:

В результате выполнения этого примера будут выведены числа 10, 20, а затем снова 10. Переменные $х в функции myfunc() и $х в основной части программы — совершенно разные. У вас может возникнуть один резонный вопрос: "Возможно ли в подпрограмме использовать как приватную, так и глобальную переменную с одним и тем же именем?" Да, но это достаточно сложный вопрос, обычно не рассматриваемый начальными учебными пособиями по Perl.

Как правило, любая подпрограмма на Perl начинается с объявления приватных переменных и присваивания массива @_ списку этих переменных:

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

Использование оператора my

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

Объявлять переменные можно даже внутри управляющей структуры, такой как for, foreach, while или if. В общем, какой бы у вас ни был блок, можно создать переменную с областью видимости внутри этого блока, как показано в следующем примере:

Здесь переменные, объявленные в операторе my, заново создаются во время каждой итерации цикла.

В Perl версии 5.004 и выше можно переменную (итератор) цикла for или foreach, a также условное выражение структур while или if объявить приватными для блока:

По окончании блока его приватные переменные аннулируются.