Иллюстрированный самоучитель по Perl

       

Пакеты


В части 11 мы упомянули о том, что область действия переменных ограничена пакетом. Рассмотрим этот вопрос более подробно.

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

package NAMESPACE;

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

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

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

    package main;

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

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



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




    #!/usr/bin/perl

    $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";

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

    package main: $х= main

    $two::x= $three::x=

    package two: $x= two

    $main::x= main $three::x=

    package main: $x= main

    package three: $x= three $main: :x= main $two::x= two

    package main: $x= main $two::x= two $three::x= three

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

  • от начала программы до вызова функции evai ();


  • после вызова функции evai о до объявления пакета package three;


  • после явного объявления пакета package main до конца файла, содержащего данную программу.


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

    С пакетом three связана часть программы от объявления package three до объявления package main.

    В каждом пакете происходит обращение к переменным из двух других пакетов при помощи указания соответствующего префикса имени переменной.

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




    Содержание раздела