Выпуск 25. Март 2015
← Про переменные и сигнатуры в Perl 6 | Содержание | Обзор CPAN за февраль 2015 г. →Модули в Perl 6
Краткий обзор основных моментов, которые полезно знать при работе с модулями в Perl 6
Тем, кто знаком с модулями в Perl 5, без труда разберутся с тем, как использовать их в Perl 6. Тем не менее, есть несколько важных отличий, которые необходимо знать перед началом работы.
Модули хранятся в файлах с тем же расширением .pm. Точно так же организуется иерархия: модуль X::Y компилятор будет искать в файле X/Y.pm в одном из предопределенных каталогов или в каталоге, указанном в опции -I при запуске из командной строки.
В теории, имена модулей не обязаны быть привязаны к файлам (а на практике сейчас имя модуля, указанное в самом модуле, похоже, вообще не используется). Однако пока про это, видимо, лучше не думать. Еще одна интересная особенность, а именно, возможность хранить и подключать один и тот же модуль, но разных версий, пока в Rakudo не реализована.
module
Модуль объявляется ключевым словом module, за которым следует название. Возможны два варианта. Объявление может быть в виде директивы в начале файла, и весь остаток файла будет телом модуля:
module X;
sub x() {
say "X::x()";
}
Второй вариант — поместить тело модуля в блок:
module X {
sub x() {
say "X::x()";
}
}
export
Переменные (my, our) и функции (sub), определяемые внутри модуля, по умолчанию не видны за его пределами. Для того, чтобы экспортировать имя, необходимо указать свойство (trait) is export:
module X;
sub x() is export {
say "X::x()";
}
Это все, что требуется для того, чтобы функцией x() удалось воспользоваться в программе, которая будет использовать модуль. Никаких многословных конструкций и манипулирования массивами @EXPORT и @EXPORT_OK больше не требуется.
use
Подключение модуля — простая операция с помощью ключевого слова use.
Сначала создаем файл Greet.pm:
module Greet;
sub hey($name) is export {
say "Hey, $name!";
}
А затем используем его:
use Greet;
hey("you"); # Hey, you!
Точно так же все работает, если имя модуля более сложное. В этом случае все импортируемые имена оказываются в текущей области видимости.
Файл Greet/Polite.pm с модулем Greet::Polite:
module Greet::Polite {
sub hello($name) is export {
say "Hello, $name!";
}
}
И программа, его использующая:
use Greet;
use Greet::Polite;
hey("you"); # функция из модуля Greet
hello("Mr. X"); # из Greet::Polite
import
Ключевое слово use автоматически выполняет импорт имен из подключаемого модуля. Однако, если модуль определен в текущем файле в лексической области видимости (обратите внимание, что можно указать модуль локальным, написав my module), автоматический импорт не произойдет, и придется сделать его явно:
my module M {
sub f($x) is export {
return $x;
}
}
import M;
say f(42);
Без принудительного импорта (import M;) обращение к функции f() из модуля приведет к ошибке. Причем импорту подвергнутся только имена, помеченные на экспорт конструкцией is export.
Обратите внимание, что импорт происходит при компиляции, поэтому имена станут доступны в программе даже выше строки про импорт:
my module M {
. . .
}
say f(1);
import M;
say f(2);
need
Если же возникнет необходимость просто загрузить модуль, но ничего из него не импортировать, следует воспользоваться ключевым словом need.
Создаем модуль N с методом n() (метод создан как our — это важно, но без is export — а это не так важно):
module N;
our sub n() {
say "N::n()";
}
И теперь указываем, что нужен этот модуль, а потом напрямую обращаемся к его методу:
need N;
N::n();
Последовательность use M; import M; (именно в таком порядке) аналогична одному use M;.
require
Ключевое слово require позволяет загрузить модуль не во время компиляции (как это делает use), а во время исполнения.
Для примера — модуль с единственной функцией, возвращающей сумму переданных ей аргументов:
module Math;
our sub sum(*@a) {
return [+] @a;
}
(Звездочка в *@a нужна, чтобы Perl свернул все аргументы в один массив, и можно было бы написать sum(1, 2, 3). Без звездочки это станет синтаксической ошибкой, поскольку метод будет ожидать массив, а не три скаляра.)
Теперь подключаем модуль с помощью require и вызываем функцию:
require Math;
say Math::sum(24..42); # 627
Если попытаться вызвать Math::sum() до require, программа не сможет найти нужное имя. При этом импортировать метод, написав import Math;, тоже не получится, поскольку импорт происходит на этапе компиляции, то есть до того, как require загрузит модуль.
Заключение
Для удобства, вот список ключевых слов Perl 6, которые потребуются при работе с модулями:
use— загрузка и импорт на этапе компиляции;need— загрузка без импорта на этапе компиляции;import— импорт имен из загруженного модуля на этапе компиляции;require— загрузка без импорта во время исполнения.
← Про переменные и сигнатуры в Perl 6 | Содержание | Обзор CPAN за февраль 2015 г. →
