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

sun*_*ica 3 perl naming module

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

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

cjm*_*cjm 6

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

my $spreadsheet_class = 'Spreadsheet::Excel';
my $sheet = $spreadsheet_class->new;
Run Code Online (Sandbox Code Playgroud)

当您在包含字符串的标量变量上调用方法时,Perl会将其视为该名称包上的类方法.没有花哨的符号表黑客需要,它的工作正常use strict.


amo*_*mon 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;
Run Code Online (Sandbox Code Playgroud)

输出:

Foo=ARRAY(0x9fa877c)
hi from Foo
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

输出:

Whatever=ARRAY(0x9740758)
hi from Foo
Run Code Online (Sandbox Code Playgroud)

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