вторник, 8 декабря 2015 г.

Реализуем отложенные функции с помощью автозагрузчика AutoLoader

Ситуация: есть большая библиотека с несколькими десятками функций, причем
львиная доля из них нам не потребуется, а только лишь несколько из них будут
востребованы, да и то не факт. В данном случае, чтобы не перетруждать перл
анализом "ненужных" функций, есть возможность отложить это занятие до того
момента, когда в какой-либо конкретной функции из библиотеки появится надобность.

Один из способов для достижения подобной задачи заключается в использовании
автозагрузчика функций - модуля AutoLoader и его помощника - модуля AutoSplit.

Для начала вспомним, что весь текст, который помещается после __END__, будет проигнорирован. Используя данный факт, поместим все те функции, которые могут быть невостребованы, после __END__.

Возьмём для примера простой модуль HelloWorld, в котором находится одна "недоступная"
функция 'hello'.

# HelloWorld.pm
package HelloWorld;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT_OK = qw/hello/;

# Экспортируя функцию AUTOLOAD из модуля AutoLoader,
# мы перекладываем на его плечи заботу по поиску и вызову
# "спрятанных" функций, так как они расположены после __END__.
use AutoLoader 'AUTOLOAD';

1;

__END__

sub hello { print "Привет мир!\n" }


Теперь, используя модуль AutoSplit, мы можем "разбить" хранящиеся функции
модуля HelloWorld. Для этого нужно вызвать функцию autosplit с именем модуля
для анализа и названием каталога для хранения проанализированных
функции (для каждой функции создастся файл вида Modulename/subname.al), в качестве
параметров.

use AutoSplit;
autosplit('HelloWorld', 'auto');

А теперь по старинке используем модуль HelloWorld.

use HelloWorld qw/hello/;

hello; # Вызов данной функции обеспечит AUTOLOAD модуля AutoLoader,
       # которая найдет её среди файлов функций *.al, затем определит
       # данную функцию (если файл был найден), дабы не тратить время 
       # на повторный поиск, при последующем вызове hello(). 

И всё вместе.
# main.pl
#!/usr/bin/perl 

use strict;
use warnings;
use v5.14;

# Данный функционал в блоке необходим лишь когда код HelloWorld
# подвергается изменениям, здесь же он расположен лишь для
# демонстрационных целей.
BEGIN {
    use AutoSplit;
    autosplit('HelloWorld', 'auto');
}

use HelloWorld qw/hello/;

hello;

Комментариев нет:

Отправить комментарий