假设您在一个文件中有一个父Perl类:
#!/usr/bin/perl
package Foo;
use strict;
use warnings;
use Data::Dumper;
sub new{
my $class = shift;
my %self = ();
return bless %self, $class;
}
1;
和不同文件中的子类:
#!/usr/bin/perl
package Bar;
use base "Foo";
1;
子类会继承父类的use语句吗?我知道new方法会被继承。
基本上,我正在尝试减少我的代码中的样板文件的数量,但我找不到这个问题的明确答案。
5条答案
按热度按时间yvt65v4c1#
你在评论中问到Test::Most以及它如何减少样板文件。看看它的
import
方法。它将模块加载到它的命名空间中,将那些符号添加到@EXPORT
中,然后通过goto
重新调用另一个import
,最终将它们放入调用命名空间中。Curtis在那里使用了一些非常厉害的黑魔法。虽然我想知道他为什么不使用 import_to_level 之类的命令。我在Avoid accidently creating methods from module exports和The Effective Perler中讨论了很多这类事情,这是在一个不同的背景下,但都是一些相同的问题。
这里有一个不同的例子。
如果其他模块加载了一个模块,你就可以访问它。但是依赖于它并不好。这里有三个独立的文件:
顶部.pm
底部.pm
测试.pl
我只在 Top.pm 中加载File::Spec。然而,一旦加载,我就可以在Perl程序中的任何地方使用它。输出显示我可以在其他文件中“使用”该模块,即使我只在一个文件中加载了它:
要使这一点起作用,加载模块的代码部分必须在其他代码部分尝试使用该模块之前加载。正如我所说,依赖于这一点是一个坏主意:如果装载顺序改变或装载模块消失,则事情中断。
但是,如果你想导入符号,你必须在你想导入的包中显式地加载你想要的模块。这只是为了让导出模块定义那个包中的符号,而不是依赖于作用域。
dy2hfwbg2#
啊,问得好!
这取决于你所说的继承是什么意思。我不会在最后做任何假设,但答案是 * 也许 *。你看,perl混合了
Classes
和Namespaces
的思想--package
是一个可以描述它们中任何一个的术语。现在的问题是use
语句,它所做的一切就是强制一个包包含,并将目标称为import()
sub。这意味着它实质上对包以及类拥有无限的控制权。现在,把perl中的所有方法与
subs
结合起来,按照惯例,subs
将$self
作为第一个参数,剩下的就是perl 5了。这对那些知道如何使用它的人来说有着巨大的好处。虽然strict是一个词法编译指示,但Moose
呢?现在,
BabyMooseUser
从哪里得到构造函数(new)?它从哪里得到 meta类?所有这些都是从父类(命名空间)中的一个use Moose;
提供的。在这里,在我们的例子中,如果 *use语句 * 的效果是添加方法,那么肯定。
这个主题比较深奥,这取决于你是在谈论编译指示,还是更模糊的对象框架,或者过程模块。如果你想在OO范式中减轻父命名空间对你自己命名空间的影响,请参阅
namespace::autoclean
。31moq8wy3#
对于样板文件缩减,我有两个策略:我的大多数类都是Moose类,它负责OO设置,也给我提供了strict和warning。如果我想在很多包中都有可用的函数,我将创建一个项目特定的
MyProject::Util
模块,它使用Sub-Exporter来提供我自己的函数和接口。这使得它更加一致。如果我决定以后不管什么原因改变转储程序,我就不必改变很多代码。这还允许你对导出进行分组。一个类通常看起来像这样:如果有其他东西你认为是样板,并希望使简单的包括,这当然取决于这些东西是什么。
q8l4jmvw4#
对您的问题的实用答案:要么使用,要么看看
Modern::Perl
是如何执行严格和警告的。mlnl4t2r5#
您可以通过检查每个包的符号表来获得明确的答案:
第一个