我们说我创建了一个名为Bar
的类。文件Bar.pm
启动
package Bar;
为避免与其他Bar
类发生冲突,我将该文件放在子目录Foo
中。所以现在,当我使用这个课时,我必须写
use Foo::Bar;
我的问题是,我是否需要将班级名称更改为Foo::Bar
?换句话说,我是否需要将Bar.pm
的第一行更改为
package Foo::Bar;
?问题是,如果我这样做,我现在必须在任何地方将该类称为Foo::Bar
,例如。
my $obj = Foo::Bar->new();
Foo::Bar->doClassMethod();
这很烦人(this question中讨论了同样的问题),特别是因为我喜欢上课方法。
答案 0 :(得分:9)
是的,您必须将package
的名称更改为与use
的名称完全匹配。
答案 1 :(得分:2)
如果您认为类名Bar
可能与名为Bar
的其他类冲突,那么只是移动文件将无济于事。如果您的程序最终同时使用Bar
和Foo::Bar
,则两者都将被加载到同一名称空间中。那时,你的程序会发生什么事情,这是任何人的猜测。
如果不想输入长类名,那么可以使用变量来保存名称。
use My::Long::Class::Name::For::Bar;
my $bar_class = 'My::Long::Class::Name::For::Bar';
$bar_class->class_method(); # the same as My::Long::Class::Name::For::Bar->class_method()
答案 2 :(得分:1)
您并不严格需要(即它是一种风格决定,而不是编译器强制执行的内容),但最好遵循perlmod / perlnewmod中规定的相关指南,以使软件易于分发。
IOW,如果长名打扰你,请找一个自动完成的编辑器。
答案 3 :(得分:1)
如果EXPR是一个单词,则require将采用“.pm”扩展名和 用文件名中的“/”替换“::”,以便于使用 加载标准模块。这种模块加载形式没有风险 改变命名空间。换句话说,如果您尝试这样做:
require Foo::Bar; # a splendid bareword
require函数实际上会查找“Foo / Bar.pm”文件 @INC数组中指定的目录。
所以,是的,如果您的模块位于$dir/Foo/Bar.pm
$dir
Foo::Bar
,那么它必须被称为{{1}}。
答案 4 :(得分:0)
包Local
仅供此用途使用。例如,如果您创建了一个包Bar.pm
,则可以调用包Local::Bar
并知道它不会与CPAN中的某些内容发生冲突。
默认情况下,@INC
包含当前目录,因此您可以创建一个Local
子目录,然后将所有包放在那里。在公司中,我会将Local
包名称空间划分为组,甚至是开发人员的名称。例如,我可以使用Local::Cm::Bar
或Local::David::Bar
。这样,如果我决定使用Alice的Bar类,我可以简单地包含Local::Alice::Bar
。
是的,标准CPAN规则声明不在程序包名称空间中使用您的名称,但Local
程序包永远不会进入CPAN。