Шаг 124.
Пакеты (общие сведения)

    На этом шаге мы приведем общие сведения о пакетах.

    Пакет - это способ создания собственного изолированного пространства имен для отдельного отрезка программы. Каждый фрагмент кода Perl-программы относится к некоторому пакету. Объявление

  package NAMESPACE;
определяет пакет NAMESPACE. Ключевое слово package является именем встроенной функции, в результате обращения к которой компилятору предписывается использовать новое пространство имен. Область действия объявления пакета определяется аналогично области видимости локальных переменных, объявленных при помощи функций my() или local(). Она распространяется либо до следующего объявления пакета, либо до конца одной из таких единиц программы:

    Область действия зависит от того, в каком месте вызвана для объявления пакета функция package(). Все идентификаторы, встретившиеся внутри этой области, принадлежат к пространству имен текущего пакета. Исключение составляют идентификаторы лексических переменных, созданных при помощи функции my().

    Объявление пакета может быть сделано несколько раз в разных точках программы. Каждое объявление означает переключение на новое пространство имен. По умолчанию предполагается, что основная программа всегда начинается с объявления пакета

  package main;

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

    К переменной из другого пакета можно обратиться, указав перед ее именем префикс, состоящий из имени этого пакета, за которым следуют два двоеточия: $PackageName::name. Такие имена условимся называть квалифицированными именами. Если имя пакета отсутствует, предполагается имя main, т.е. записи $::var и $main::var обозначают одну и ту же переменную.

    Специальная лексема __PACKAGE__ служит для обозначения имени текущего пакета.

#! perl -w
$x= __PACKAGE__;
print "package $x:\n";
print "\$x= $x\n";
print "\$two::x= $two::x\n";
print "\$three::x= $three::x\n";
eval 'package two;
  $x= __PACKAGE__;
  print "    package $x:\n";
  print "\$x= $x\n";
  print "\$main::x= $main::x\n";
  print "\$three::x= $three::x\n";';

print "package $x:\n";
print "\$x= $x\n";

package three;
$x= __PACKAGE__;
print "package $x:\n";
print "\$x= $x\n";
print "\$main::x= $main::x\n";
print "\$two::x= $two::x\n";

package main;
print "package $x:\n";
print "\$x= $x\n";
print "\$two::x= $two::x\n";
print "\$three::x= $three::x\n";
Текст этого примера можно взять здесь.

    В результате выполнения будут выведены следующие значения:


Рис.1. Результат работы скрипта

    В данном примере используются три пакета, каждый со своим пространством имен: main, two, three. В каждом пакете определена переменная , значение которой совпадает с именем пакета. С пакетом main связаны следующие отрезки программы:

    Для выражения, выполняемого функцией eval(), определено собственное пространство имен two. Оно действует только в пределах этого выражения. Если бы внутри функции eval() не был определен собственный пакет two, все действия внутри нее были связаны с пакетом, в котором функция eval() была скомпилирована, т. е. с пакетом main.

    С пакетом three связана часть программы от объявления package three до объявления package main. В каждом пакете происходит обращение к переменным из двух других пакетов при помощи указания соответствующего префикса имени переменной.

    Компилятор создает для каждого пакета отдельное пространство имен. Переменным из разных пакетов присваиваются их значения по мере выполнения соответствующего кода программы. Вот почему при первом обращении из пакета main к переменным two::$x и $three::x их значения еще не определены.

    На следующем шаге мы рассмотрим таблицы символов.




Предыдущий шаг Содержание Следующий шаг