Как «использовать» несколько модулей одним «использованием»? - PullRequest
13 голосов
/ 27 июня 2011

Я хочу использовать несколько пакетов и некоторые прагмы во всех моих программах, например:

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;

НЕ РАБОТАЕТ.Получил ту же ошибку.


Есть рабочая идея?

Ответы [ 3 ]

8 голосов
/ 27 июня 2011

Это на самом деле довольно просто, если вы переопределите метод import вашего "общего" модуля.См. Источник модуля Modern :: Perl chromatic для примера экспорта прагм.

Для реэкспорта вещей, определенных в других модулях, я напоминаю, что $export_to_level (см. Экспортер Документы, хотя это не объясняется так же ясно) должны это сделать, хотя я не могу найти хороших примеров на данный момент.Другой вариант будет Pollute :: persistent , хотя я не использовал его, не знаю никого, кто использовал его, и не может сказать, насколько стабильным / твердым он может быть.Однако, если это работает, возможно, это самый быстрый и простой вариант.

8 голосов
/ 27 июня 2011

Я бы пошел с этим:

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; к каждому сценарию:

use My::Common;
use autodie;
# ...
3 голосов
/ 27 июня 2011

Я только что заметил модуль под названием rig в CPAN.Попробуйте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...