为Perl中的模块提供备用名称

时间:2013-08-31 12:34:42

标签: perl module naming

Perl是否可以为模块分配新名称以便在我们的代码中使用?

我的目的是:我的一些客户想要.xls文件(Spreadsheet :: Excel)和其他.xlsx(Excel :: Writer :: XLSX)。由于这两个模块共享大部分API,我希望能够在项目开始时在某个地方设置一次该选项,然后忘记它,这也可以在将来轻松更改它。它也可能用于鼠标/驼鹿变化之类的东西。

2 个答案:

答案 0 :(得分:6)

看起来您真正想要的是能够在名称在运行时确定的类上调用类方法(如new)。这其实很简单:

my $spreadsheet_class = 'Spreadsheet::Excel';
my $sheet = $spreadsheet_class->new;

当您在包含字符串的标量变量上调用方法时,Perl会将其视为该名称包上的类方法。不需要花哨的符号表黑客,它在use strict下工作得很好。

答案 1 :(得分:5)

您可以将类的包藏匿处别名为新名称:

use strict; use warnings; use feature 'say';

package Foo;
sub new { bless [] => shift }
sub hi  { say "hi from Foo" }

package main;

# Alias the package to a new name:
local *F:: = *Foo::;  # it could make sense to drop the "local"

# make an objects
my $f = F->new;

# say hi!
say $f;
$f->hi;

输出:

Foo=ARRAY(0x9fa877c)
hi from Foo

另一种解决方案是动态子类化您想要的包。

use strict; use warnings; use feature 'say';

package Foo;
sub new { bless [] => shift }
sub hi  { say "hi from Foo" }

package Whatever;
# no contents

package main;

# let Whatever inherit from Foo:
# note that I assign, instead of `push` or `unshift` to guarantee single inheritance
@Whatever::ISA = 'Foo'; 

# make an objects
my $w = Whatever->new;

# say hi!
say $w;
$w->hi;

输出:

Whatever=ARRAY(0x9740758)
hi from Foo

这两种解决方案都在运行时工作,非常灵活。第二种解决方案依赖于较少的魔力,看起来更清洁。但是,模块可能会测试ref($obj) eq 'Foo'而不是正确的blessed $obj and $obj->isa('Foo'),这可能会导致破损。