我有一个我刚刚创建的包,我有一个“旧模式”,它基本上使它像以前一样工作:将所有内容导入当前命名空间。将此作为一个包的一个好处是我们不再需要这样做。无论如何,我想做的就是让任何人都这样做:
use Foo qw(:oldmode);
我发出警告说这是不推荐的,他们应该只导入他们需要的东西,或者只使用Foo-> fun()访问函数;
关于如何做到这一点的任何想法?
答案 0 :(得分: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')};
}
因此,在子import
中,您可以在参数列表中搜索已弃用的标记,然后发出警告。
更新:正如Axeman指出的那样,您应该致电goto &{Exporter->can('import')}
。这种形式的goto替换堆栈上的当前子例程调用,保留当前参数(如果有的话)。这是必需的,因为Exporter的import()方法将导出到其调用者的命名空间。
答案 1 :(得分: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用于我的代码的所有方法。
注意:在导入子中使用导出器的标准方法是操纵$Exporter::ExportLevel
或调用Foo->export_to_level( 1, @_ );
但我喜欢上面的方法。它更快,我认为更简单。