Задача. Есть скрипт на языке программирования Perl. В нем определена какая-то функция (саба). Нужно заиспользовать эту функцию в другом скрипте.
Задача. Есть скрипт на языке программирования Perl. В нем определена какая-то функция (саба). Нужно заиспользовать эту функцию в другом скрипте.
Вот пример. Есть скрипт script.pl
в котором определена саба header
. В эту сабу передаешь
строку, и она возвращает эту строку в виде markdown заголовка. В этом скрипте эта саба
используется для того чтобы вывести на экран два заголовка:
#!/usr/bin/perl
use feature qw(say);
sub header {
my ($string) = @_;
return '## ' . uc($string);
}
say header('one');
say header('two');
Запускаем perl script.pl
и видим на экране:
## ONE
## TWO
Задача — создать еще один скрипт other.pl
который тоже будет использовать эту сабу.
Самое простое (но плохое) решение — это просто скопировать код сабы в другой скрипт. При таком решении получается
вот такой other.pl
:
#!/usr/bin/perl
use feature qw(say);
sub header {
my ($string) = @_;
return '## ' . uc($string);
}
say header('three');
Теперь можно запустить этот скрипт perl other.pl
и увидеть на экране текст ## THREE
.
Это решение задачи, но это плохое решение. Из-за того что один и тот же код находится в нескольких файлах становится сложно работать с таким кодом. Когда понадобится изменить эту сабу, то придется менять ее в нескольких местах (и еще нужно будет не забыть поменять код во всех нужных файлах).
Наиболее правильное решение, — это вынести сабу в отдельный модуль. Для этого
создаем файл lib/Utils.pm
:
package Utils;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
header
);
our @EXPORT = @EXPORT_OK;
sub header {
my ($string) = @_;
return '## ' . uc($string);
}
1;
package Utils;
- объявили что это "библиотека" Utils
use strict;
и use warnings;
— включаем режим чтобы Perl был более требователен к хорошему коду
EXPORT
говорят о том что при подключении этой "библиотеки" нужно чтобы функция header
была доступна
1;
— package всегда должен заканчиваться истиной
После этого описание функции нужно из скрипта script.pl
убрать, но добавить подключение библиотеки:
#!/usr/bin/perl
use feature qw(say);
use Utils;
say header('one');
say header('two');
После этого можно запустить этот же скрипт с помощью команды perl -Ilib/ script.pl
.
В ключ командной строки -I
передаем значение lib/
— папка в которой Perl будет
искать библиотеки. Результат работы этого скрипта точно такой же как и раньше.
И теперь совершенно тривиально заиспользовать эту же сабу в другом скрипте. Пишем
скрипт other.pl
, который практически такой же как script.pl
:
#!/usr/bin/perl
use feature qw(say);
use Utils;
say header('three');
Запускаем этот скрипт perl -Ilib/ other.pl
и видим на экране ## THREE
.
Существует еще одно решение как можно использовать сабу определенную в скрипте script.pl
заиспользовать в скрипте other.pl
. Для этого пишем такой текст в файл other.pl
:
#!/usr/bin/perl
use feature qw(say);
require './script.pl';
say header('three');
Запускаем скрипт perl other.pl
(файл other.pl
должен быть в той же папке что и скрипт script.pl
).
Результат:
## ONE
## TWO
## THREE
Т.е. получилось что при выполнении скрипта other.pl
сначала был выполнен весь код, который
был в script.pl
(строки ## ONE
и ## TWO
), а только потом выполнен код из скрипта
other.pl
(строка ## THREE
).
Для того чтобы при запуске скрипта other.pl
не выполнялась часть script.pl
нам нужно немного
изменить script.pl
. Нужно завернуть весь код в теле скрипта под условие и вписать в конец скрипта
единицу как истинное значение:
#!/usr/bin/perl
use feature qw(say);
sub header {
my ($string) = @_;
return '## ' . uc($string);
}
if ( not caller() ) {
say header('one');
say header('two');
}
1;
Теперь если мы запустим perl script.pl
, то получим точно такой же вывод как и раньше, а
если запустим perl other.pl
, то в выводе будет только нужный нам текст ## THREE
.
Ключевое слово caller
возвращает разные значение в зависимости от того как был запущен
скрипт. Эту фичу мы используем здесь для того чтобы разделить запуск скрипта напрямую
от подключения скрипта с использованием require
.