4

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

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

4

2 回答 2

6

您可以将类的包存储别名为新名称:

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'),这可能会导致损坏。

于 2013-08-31T12:55:11.677 回答
6

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

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

当您在包含字符串的标量变量上调用方法时,Perl 将其视为该名称的包上的类方法。不需要花哨的符号表技巧,它在use strict.

于 2013-08-31T17:41:28.100 回答