我正在用OO编写一个Perl模块Galaxy::SGE::MakeJobSH
。
我想使用MakeJobSH->new()
代替Galaxy::SGE::MakeJobSH->new()
,
或其他一些短名称。我怎么能这样做?
答案 0 :(得分:12)
您可以建议您的用户使用aliased模块加载您的用户:
use aliased 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();
或者您可以在名为$MakeJobSH
;
use Galaxy::SGE::MakeJobSH; # Assume this exports $MakeJobSH = 'Galaxy::SGE::MakeJobSH';
my $job = $MakeJobSH->new();
或者你可以导出一个返回你的类名的MakeJobSH函数:
use Galaxy::SGE::MakeJobSH; # Assume this exports the MakeJobSH function
my $job = MakeJobSH->new();
但是,我不确定这是一个多么伟大的想法。人们通常不必经常输入类名。
以下是您在课堂上为最后两个选项所做的事情:
package Galaxy::SGE::MakeJobSH;
use Exporter 'import';
our @EXPORT = qw(MakeJobSH $MakeJobSH);
our $MakeJobSH = __PACKAGE__;
sub MakeJobSH () { __PACKAGE__ };
当然,您可能只想选择其中一种方法。我只是将它们结合起来以避免重复示例。
答案 1 :(得分:3)
我不打扰别名。我认为这是错误的方式。如果你只是寻找更少的类型,它可能是答案(但是新的依赖性比风险更有益吗?)。我不喜欢通过隐藏真实姓名来欺骗维护程序员的想法,因为别名发生了很长的距离,并且没有任何迹象表明看起来类名不是真正的类。
我主要是寻找简单的子类,所以我让班级自己决定哪个模块将实现一个部分。
例如,我可能从一个想要使用Foo
来处理部分工作的类开始。我知道我可能希望稍后继承Foo
,所以我不会对其进行硬编码:
package Foo::Bar;
sub foo_class { 'Foo' }
sub new {
....
eval "require $self->foo_class";
$self->foo_class->do_something;
}
在应用程序中,我选择使用'Foo :: Bar':
#!perl
use Foo::Bar;
my $obj = Foo::Bar->new();
后来,我需要专门化Foo,所以我创建一个子类覆盖了我需要的部分:
package Foo::Bar::Baz;
use parent 'Foo::Bar';
sub foo_class { 'Local::Foo::SomeFeature' }
1;
另一个应用程序使用了几乎所有相同的东西,但是使用了小调整:
#!perl
use Foo::Bar::Baz;
my $obj = Foo::Bar::Baz->new();
如果你想编写一个程序并让用户通过配置选择类,你也可以在应用程序级别做类似的事情。
答案 2 :(得分:2)
谢谢cjm。
我只是选择内联别名。
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(MakeJobSH);
sub MakeJobSH() {return 'Galaxy::SGE::MakeJobSH';}
答案 3 :(得分:1)
别名效果很好。如果要将一个名称空间的全局别名设置为另一个名称空间,请改用Package::Alias。
答案 4 :(得分:1)
它与aliased
几乎完全相同,但使用标准的Perl模块:
use constant MakeJobSH => 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();