在 Perl 中是否可以为模块分配一个新名称以在我们的代码中使用?
我的目的是:我的一些客户想要 .xls 文件(电子表格::Excel)和其他 .xlsx(Excel::Writer::XLSX)。由于这两个模块共享它们的大部分 API,我希望能够在项目开始时在某个地方设置一次该选项,然后忘记它,这也便于将来更改它。它也可能用于诸如鼠标/驼鹿变化之类的事情。
您可以将类的包存储别名为新名称:
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')
,这可能会导致损坏。
看来您真正想要的只是能够new
在名称在运行时确定的类上调用类方法(如 )。这实际上很简单:
my $spreadsheet_class = 'Spreadsheet::Excel';
my $sheet = $spreadsheet_class->new;
当您在包含字符串的标量变量上调用方法时,Perl 将其视为该名称的包上的类方法。不需要花哨的符号表技巧,它在use strict
.