Как "использовать" несколько модулей с одним "использованием"?
Я хочу использовать некоторые пакеты и некоторые прагмы во всех моих программах, например:
use 5.014;
use warnings;
use autodie;
use My::ModuleA::Something;
use ModuleB qw(Func1 Func2);
Я не хочу повторять себя в каждом модуле, поэтому ищу способ сделать один пакет, например. My::Common
то, что будет содержать вышеуказанные пакеты, и в моих программах делать только:
use My::Common;
say Func1("hello"); #say enabled and Func1 imported in the My::Common
как добиться этого?
Было прочитано preldoc -f use
и perldoc perlmodlib
, поэтому я думаю, что я должен "немного" сделать это с помощью BEGIN plus require & import, но абсолютно не знаю, как это сделать.
ОБНОВЛЕНИЕ: Я уже пробовал основные вещи.
С помощью require
- моей программы prg.pl.
require 'mymods.pl';
$var = "hello";
croak "$var\n";
mymods.pl содержит
use strict;
use feature 'say';
use Carp qw(carp croak cluck);
1;
НЕ РАБОТАЕТ. Получена ошибка:
$ perl prg.pl
String found where operator expected at prg.pl line 3, near "croak "$var\n""
(Do you need to predeclare croak?)
syntax error at prg.pl line 3, near "croak "$var\n""
Execution of prg.pl aborted due to compilation errors.
с помощью "use My":
use My;
$var = "hello";
croak "$var\n";
my My.pm
package My;
use strict;
use feature 'say';
use Carp qw(carp croak cluck);
1;
НЕ РАБОТАЕТ. Получена такая же ошибка.
Любая рабочая идея?
Ответы
Ответ 1
Я бы пошел с этим:
package My::Common;
use 5.14.0;
use strict;
use warnings;
use autodie;
use Carp qw(carp croak cluck);
sub import {
my $caller = caller;
feature->import(':5.14');
# feature->import('say');
strict->import;
warnings->import;
## autodie->import; # <-- Won't affect the caller side - see my edit.
{
no strict 'refs';
for my $method (qw/carp croak cluck/) {
*{"$caller\::$method"} = __PACKAGE__->can($method);
}
}
}
1;
Пожалуйста, поправьте меня, если я ошибаюсь, или там лучший способ.
ИЗМЕНИТЬ
Извините, я ошибся в использовании autodie->import
...
Это должно работать, но предполагается, что вы всегда вызываете My::Common
из пакета main
:
package My::Common;
# ...
sub import {
# ...
strict->import;
warnings->import;
{
package main;
autodie->import;
}
# ...
}
Итак, конечно, гораздо безопаснее и проще добавлять use autodie;
к каждому script:
use My::Common;
use autodie;
# ...
Ответ 2
Это на самом деле довольно просто, если вы переопределите свой "общий" модуль import
. См. Источник хроматического Modern:: Perl для примера экспорта прагм.
Для повторного экспорта вещей, определенных в других модулях, я, кажется, напоминаю, что $export_to_level
(см. Exporter docs, хотя это не объясняет все это ясно), должен сделать это, хотя я не могу найти хороших примеров на данный момент. Другим вариантом будет Pollute::persistent, хотя я не использовал его, не знаю никого, кто его использовал, и не может скажем, насколько он стабилен/тверд. Если это сработает, это, вероятно, самый быстрый и простой вариант.
Ответ 3
Я только что заметил модуль CPA, называемый rig. Попробуйте.