6

我有一个我刚刚制作的包,我有一个“旧模式”,它基本上使它像以前一样工作:将所有内容导入当前命名空间。将其作为一个软件包的好处之一是我们不再需要这样做。无论如何,我想做的是拥有它,以便每当有人这样做时:

use Foo qw(:oldmode);

我发出警告说,这已被弃用,他们应该只导入他们需要的东西,或者只使用 Foo->fun(); 访问函数。

关于如何做到这一点的任何想法?

4

2 回答 2

12

您编写自己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')};
}

因此,在 sub 中import,您可以在参数列表中搜索已弃用的标签,然后发出警告。

更新:正如 Axeman 指出的那样,您应该调用goto &{Exporter->can('import')}. 这种形式的 goto 替换堆栈上的当前子例程调用,保留当前参数(如果有)。这是必需的,因为 Exporter 的 import() 方法将导出到其调用者的命名空间。

于 2008-10-09T14:31:55.147 回答
11

好吧,正如您特别声明的那样,您想在这种情况下发出警报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 的所有方法。

注意:在 import sub 中使用 exporter 的标准方法是操作$Exporter::ExportLevel或调用Foo->export_to_level( 1, @_ );但我喜欢上面的方式。它更快,我认为,更简单。

于 2008-10-09T14:56:10.747 回答