Как я могу заставить Perl выдавать предупреждающее сообщение при импорте определенного пакета / тега? - PullRequest
6 голосов
/ 09 октября 2008

У меня есть пакет, который я только что сделал, и у меня есть «старый режим», который в основном заставляет его работать так, как он работал раньше: импортировать все в текущее пространство имен. Одна из приятных сторон использования этого пакета в том, что нам больше не нужно это делать. В любом случае, я хотел бы, чтобы это было так, чтобы всякий раз, когда кто-либо делал:

use Foo qw(:oldmode);

Я выдаю предупреждение, что это устарело и что они должны либо импортировать только то, что им нужно, либо просто получать доступ к функциям с помощью Foo-> fun ();

Есть идеи, как это сделать?

Ответы [ 2 ]

12 голосов
/ 09 октября 2008

Вы пишете свои sub import в package Foo, которые будут вызываться со списком параметров из use Foo.

Пример:

package Foo;
use Exporter;

sub import {
    warn "called with paramters '@_'";

    # do the real import work
    goto &{Exporter->can('import')};
}

Таким образом, в подпункте import вы можете найти в списке аргументов устаревший тег и затем выдать предупреждение.

Обновление : Как указывает Аксеман, вам следует позвонить goto &{Exporter->can('import')}. Эта форма goto заменяет текущий вызов подпрограммы в стеке, сохраняя текущие аргументы (если есть). Это необходимо, потому что метод import () Экспортера будет экспортировать в пространство имен вызывающего.

11 голосов
/ 09 октября 2008

Ну, так как вы специально заявляете, что хотите вызвать тревогу в случаях use Mod qw<:oldmode>; Это работает лучше:

package Foo;
use base qw<Exporter>;
use Carp qw<carp>;
...
sub import { 
    #if ( grep { $_ eq ':oldmode' } @_ ) { # Perl 5.8
    if ( @_ ~~ ':oldmode' ) {              # Perl 5.10 
        carp( 'import called with :oldmode!' );
    }
    goto &{Exporter->can( 'import' )};
}

Спасибо Frew за упоминание синтаксиса интеллектуального сопоставления Perl 5.10. Я изучаю все способы работы с Perl 5.10 в моем коде.

Примечание: стандартный способ использовать экспортер в подпрограмме импорта - это либо манипулировать $Exporter::ExportLevel, либо вызывать Foo->export_to_level( 1, @_ ); Но мне нравится вышеуказанный способ. Это быстрее и, я думаю, проще.

...