проверить параметры для «использования», а остальные передать? - PullRequest
4 голосов
/ 09 марта 2010

У меня есть модуль Perl, и я хотел бы иметь возможность выбирать параметры, которые пользователь моего модуля передал в вызове "use". Кого бы я не узнал, я бы хотел передать. Я попытался сделать это, переопределив метод "import", но мне не очень повезло.

EDIT:

Чтобы уточнить, как это, я могу использовать мой модуль так:

use MyModule qw/foo bar/;

, который будет импортировать foo и bar методы MyModule . Но я хочу сказать: 1016

use MyModule qw/foo doSpecialStuff bar/;

и найдите doSpecialStuff , чтобы проверить, нужно ли мне делать какие-то особые вещи в начале программы, затем передайте qw / foo bar / в экспорта

Экспортера

Ответы [ 3 ]

8 голосов
/ 09 марта 2010

Обычно вы делаете это для получения Exporter функциональных возможностей import () (это не единственный способ, но это распространенный метод, который работает):

package MyClass;
use strict;
use warnings;
use Exporter 'import';  # gives you Exporter's import() method directly
our @EXPORT_OK = qw(stuff more_stuff even_more_stuff);

... и тогда вы получите автоматически созданный метод import(). Однако, если вы хотите сделать что-то дополнительное в import() до того, как обычный метод получит параметры, не импортируйте import() Exporter и определите свой собственный, который вызывает import() Exporter после внесения любых изменений в список аргументов, который вам нужен:

package MyClass;
use strict;
use warnings;
use parent 'Exporter';

sub import
{
    my ($class, @symbols) = @_;

    # do something with @symbols, as appropriate for your application
    # ...code here left as an exercise for the reader :)

    # now call Exporter's import, and import to the right level
    local $Exporter::ExportLevel = 1;
    $class->SUPER::import(@symbols);
}

Однако мне интересно, зачем вам это нужно ... стандартное поведение умирания при пропуске нераспознанного символа, как правило, хорошо. Почему вы хотите игнорировать нераспознанные символы? ( Редактировать: Теперь я вижу, что вы хотите указать дополнительное поведение поверх импортируемых символов, что не является редкостью в Perl. Так что определение собственного метода import () определенно является подходом, чтобы захватить здесь эти значения.)


PS. если вы хотите импортировать только те символы, которые определены @EXPORT_OK, это может быть реализовано так:

@symbols = grep {
    my $sym = $_;
    grep { $_ eq $sym } @EXPORT_OK
} @symbols;

3 голосов
/ 09 марта 2010

Типичное использование Exporter состоит в том, чтобы объявить ваш модуль унаследованным от Exporter, и чтобы метод Exporter import вызывался неявно при использовании вашего модуля.Но это удерживает вас от создания собственного метода import для вашего модуля.

Обходной путь - использовать метод Exporter export_to_level, который выполняет функции Exporter без явного переходачерез метод Exporter::import.Вот типичный способ его использования:

package My::Module;
use base 'Exporter';   # or use Exporter; our @ISA=qw(Exporter);
our @EXPORT = qw(...);
our @EXPORT_OK = qw(...);
our %EXPORT_TAGS = (...);

sub import {
    my ($class,@import_args) = @_;
    my @import_args_to_pass_on = ();
    foreach my $arg (@import_args) {
       if (... want to process this arg here ...) {
          ...
       } else {
          push @import_args_to_pass_on, $arg;
       }
    }
    My::Module->export_to_level(1, "My::Module", @import_args_to_pass_on, @EXPORT);
    #or:  $class->export_to_level(1, $class, @import_args_to_pass_on, @EXPORT);
}
2 голосов
/ 09 марта 2010

Я сделал это в своих модулях:

sub import {
    return if not @_;
    require Exporter;
    my $pkg = shift;

    # process @_ however you want

    unshift @_, $pkg;
    goto &Exporter::import;
}

вы также можете наследовать от Exporter, если вы хотите отменить импорт и тому подобное.

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