如何在Perl中重命名导出的函数?

时间:2009-04-29 11:36:03

标签: perl exporter typeglob

我有一些导出各种功能的Perl模块。 (我们多年来没有在新模块中使用@EXPORT,但保留了它以与旧脚本兼容。)

我已经重命名了许多函数和方法来更改为一致的命名策略,并认为然后添加一个行列表,如

*directory_error      = *directoryError;
模块末尾的

只会将旧名称别名为new。

这是有效的,除非导出旧名称,并且调用脚本使用非限定名称调用该函数:在这种情况下,它报告未找到子例程(在调用模块中)。

我想现在发生的事情是,当别名尚未创建时,Exporter会在BEGIN中准备列表;但我尝试将typeglob赋值放在BEGIN块中,但没有帮助。

我已经尝试过AUTOLOAD,但当然这并没有使这个名字在调用上下文中可用。当然我可以编写一系列包装函数,但这很乏味。我可以自动生成包装函数,但我不确定如何。

有任何关于处理此问题的简洁方法的建议吗?

3 个答案:

答案 0 :(得分:1)

以下适用于我。这似乎就是你所描述的;你一定是在某个地方弄错了。

主要剧本:

use strict;
use warnings;
use Bar;

baz();

模块:

package Bar;
use strict;
use warnings;

require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(baz);

sub Baz { print "Baz() here\n" }

*baz = *Baz;

1;

答案 1 :(得分:1)

导出

手动调用@EXPORT =()的东西变得有点憔悴。

package Bar;
use strict;
use warnings;

use Sub::Exporter -setup => {
    exports => [qw[ foo ]],
    groups  => {
        default => [qw[ foo ]],
    }
};

sub foo(){

};


1;

使用:

use strict;
use warnings;
use Bar  foo => { -as-> 'Foo' }; 

Sub :: Exporter可以做很多很棒的事情,比如组导出,组排除,构建器方法(即:它导出的子工作如何通过传递的参数确定,而subs在其他子元素中生成等)< / p>

重命名

对于重命名事物,最好有一个辅助函数,它只是作为一个遗留函数,Carp()在调用它时推荐指向它的代码移动到新方法。这将增加代码范围内的一致性。

然后,当您的测试停止发出警告时,您可以删除旧功能。

sub old {  # line 1
   Carp::carp('Legacy function \'old\' called, please move to \'newmethod\' '); 
   goto &newmethod; # this passes @_ literally and hides itself from the stack trace. 
} # line 4

sub newmethod { # line 6
   Carp::cluck('In New Method'); 
   return 5;
} # line 9

print old(), "\n";  # line 11
Legacy function 'old' called, please move to 'newmethod' at code.pl line 2
    main::old() called at code.pl line 11
In New Method at code.pl line 7
    main::newmethod() called at code.pl line 11
5

请注意newmethod中的警告看起来与他们直接调用的方式完全相同。

答案 2 :(得分:0)

如果您希望两个名称都可见,则必须导出这两个名称。以Michael Carman的答案为基础,你需要

our @EXPORT = qw(Baz baz);

our @EXPORT    = qw(Baz);
our @EXPORT_OK = qw(baz);

如果你想在程序中调用任何一个。仅仅因为它们指向相同的coderef并不意味着该代码的所有名称都将被导出。