Хотелось бы сегодня вкратце рассказать об обширной области Perl - о модулях, пакетах, классах и работе с ними. В следующих статьях я расскажу о наследовании и связывании переменных (это тоже имеет отношение к классам). Материал рассчитан на начинающих, но по битам разжевывать не буду. Для более подробного изучения следует обратиться к мануалам Perl. Очередной раз рекомендую книгу Perl Programming издательства O'Reilly (Программирование на Perl - переводное русскоязычное издание издательства Символ), среди авторов которой присутствует имя создателя Perl - Ларри Уолла.
Что такое модуль? Это отдельный файл с частью программы.
Что такое пакет? Это пространство имен, обозначаемое командой package.
Что такое класс? Это то же самое, что и пакет.
Что такое объект? Это ссылка на любой встроенный тип данных, "освященная" командой bless.
Что такое связанная переменная? Это переменная (не ссылка), "связанная" с классом командой tie.
На самом деле никаких ограничений нет, но, если придерживаться некоторых правил, то это уменьшит вероятность ошибки в коде.
Имена переменных и функций принято начинать с маленькой (строчной) буквы, а имена пакетов (классов) и модулей - с большой (прописной).
Вообще, имена модулей допустимо именовать как угодно, но если вы используете для загрузки команды use или require с "голыми" именами, то правильно будет именовать именно с большой буквы.
Расширение имен файлов (суффикс) принято такое: pl - для главного модуля, pm - для загружаемых модулей.
Модуль не требует никакого особого оформления. Если модуль содержит одноименный пакет, то обычно его начинают с команды package.
# файл Example1.pm
package Example1;
Загружают модуль командами use и require. Команда use загружает модуль на этапе компиляции, когда Perl находит ее в процессе синтаксического разбора. Команда require загружает модуль на этапе исполнения, когда логика выполнения доходит до этой команды.
Форматы команд:
# Загружает модуль Module.pm
use Module;
# загружает модуль Dir1/Dir2/Module.pm
use Dir1::Dir2::Module;
# Загружает модуль и импортирует из него в текущее пространство имен имена name1, name2 и name3
# Требуется наличие в модуле одноименного пакета и метода import
use Module qw(name1 name2 name3);
# Загружает файл, заданный выражением
use EXPR;
Команда require имеет точно такой же формат.
Загружаемые файлы ищутся в директориях, указанных в массиве @INC. Имена успешно загруженных модулей помещаются в хеш %INC (имя используются в качестве ключа, а значение содержит полный путь к файлу).
Если есть неуверенность в том, что модуль существует, и нужно обработать ошибку, то можно применить блок eval.
eval { require Module; };
if ($@)
{
# error...
}
Также можно обратить внимание на команду do в форме со строковым выражением.
Как я уже написал выше, пакет - это пространство имен. В одном файле можно последовательно объявлять несколько пакетов, а также можно объявлять несколько раз один и тот же пакет. Команда package влияет на интерпретацию имен глобальных переменных, у которых не указано имя пакета (не квалифицированные имена), в том числе на переменные, объявленные с ключевым словом local, и действует до конца блока, в котором она определена, либо до следующего переназначения пакета. На ранее объявленные переменные с ключевым словом our команда не влияет.
Пакетом по умолчанию является main. Встроенные команды находятся в пакете Core.
package Class1;
$x = 1; # $Class1::x
package Class2;
$x = 2; # $Class2::x
package Class1;
print $x; # $Class1::x
print $Class2::x;
Объект создается методом "освящения" ссылки на встроенный тип данных именем класса с помощью команды bless. Функция ref() возвращает для такой ссылки имя класса.
Методы класса являются простыми функциями пакета и отличаются тем, что в качестве первого параметра в метод передается ссылка на объект или имя класса, если метод вызван как статический.
Статические члены класса определяются как глобальные переменные пакета.
Данные объекта полностью динамичны и зависят от используемого типа ссылки. Чаще всего применяют хеш - это позволяет использовать именованные данные.
В Perl для конструктора нет зарезервированного имени, как в C++. Любая функция может быть конструктором. Конструктора может вообще не быть - связать ссылку с классом можно в любом месте программы. Для деструктора в Perl принято имя DESTROY. Деструктор вызывают во время уничтожения объекта при сборке мусора. То есть, если нужно высвободить какие-либо ресурсы типа файлов или подключений к БД, то лучше сделать отдельный метод и принудительно его вызывать.
package Class1;
# самый примитивный конструктор
sub simple
{
return bless {};
}
# классический пример конструктора, поддерживающего наследование
sub new
{
my $invocant = shift; # первый параметр - ссылка на объект или имя класса
my $class = ref($invocant) || $invocant; # получение имени класса
my $self = { @_ }; # ссылка на анонимный хеш - это и будет нашим новым объектом, инициализация объекта
bless($self, $class); # освящаем ссылку в объект
return $self; # возвращаем объект
}
# пример деструктора
sub DESTROY
{
my $self = shift;
# тут можно выполнить какие-либо действия
}
# варианты использования конструктора для создания объекта
my $object1 = new Class1;
my $object2 = Class1->new('param1', 1, 'param2', 'abc', param3 => 333);
my $object3 = $object1->new();
В вышеприведенном примере конструктора применены некоторые ухищрения.
my $class = ref($invocant) || $invocant;
Получение имени класса.
Если дочерний класс использует в качестве конструктора метод родительского класса, то он автоматом получит в качестве первого параметра имя дочернего класса. Если же передать ссылку на объект, то будет создан новый объект того же типа.
my $self = { @_ };
Инициализация объекта.
Этого можно не делать или предварительно разобрать и проверить параметры. Просто это удобная форма инициализации.
Метод можно вызывать как статический (используя имя класса) или как метод объекта (используя ссылку на объект). Кроме того, есть две синтаксические формы записи.
# классическая синтаксическая форма - взята из C++
$object->method($arg1, $arg2, $arg3); # метод объекта
Class1->method($arg1, $arg2, $arg3); # метод класса
# вторая синтаксическая форма
method $object $arg1, $arg2, $arg3; # метод объекта
method Class1 $arg1, $arg2, $arg3; # метод класса
Заметьте, что во второй форме аргументы после объекта отделяются символами пробелов, а не запятой.
Классическая форма предпочтительнее, т.к. более однозначна с точки зрения синтаксиса. Совсем однозначно будет, если после имени класса поставить "::".
method Class1:: $arg1, $arg2, $arg3;
Class1::->method($arg1, $arg2, $arg3);
Не стоит путать вызов метода с вызовом функции. Ведь в этом случае первым параметром не передается имя класса - параметров на один меньше.
Class1::method($arg1, $arg2, $arg3); # вызов функции
Если этого маленького ликбеза вам недостаточно - посмотрите мануалы, идущие с Perl. В непонятных случаях
задавайте вопросы на наш форум. Одна только просьба: конкретизируйте, пожалуйста, ваши вопросы.