大佬教程收集整理的这篇文章主要介绍了Perl OOP:在自己的模块中外包方法是个好主意吗,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在考虑将模块的各个方法移动到单独的模块中,以获得更易于管理的文件。我为此写了一个小测试:
a.pl:
val result = formats.map { ... }
下午:
#!/usr/bin/perl
use 5.028;
use warnings;
use utf8;
use open ':std',':enCoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use Benchmark qw(:all);
use A;
our $VERSION = 1;
Readonly::Scalar my $COUNT => 10_000_000;
warn $A::VERSION;
warn $A::Login2::VERSION;
my $a = A->new;
warn $a;
$a->login(1);
$a->login2(1);
cmpthese($COUNT,{
login => sub{$a->login},login2 => sub{$a->login2}
});
A/Login2.pm:
package A;
use 5.028;
use warnings;
use utf8;
use open ':std',':enCoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use A::Login2 'login2';
our $VERSION = 1;
sub new {
my ($class,$p) = @_;
my $this = {};
bless $this,$class;
return $this;
}
sub login {
my ($this,$dump) = @_;
if ($dump) {
warn "$this: login";
$this->test;
}
return;
}
sub test {
my ($this) = @_;
warn "$this: test";
return;
}
1;
./a.pl 的输出是:
package A::Login2;
use 5.028;
use warnings;
use utf8;
use open ':std',':enCoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use base 'Exporter';
our @EXPORT_OK = qw(login2);
our $VERSION = 1.1;
sub login2 {
my ($this,$dump) = @_;
if ($dump) {
warn "$this: login2";
$this->test;
}
return;
}
1;
我会认为 login 比 login2 快。
我期待着评论。
@H_801_0@解决方法这是一个关于设计的开放式问题,但我会提供一些具体的评论。
首先,为了便于管理和可读性而拆分笨重的文件是值得称道的,这通常是一个好主意。我们use
在我们编写的任何大量代码中都使用了库——所以就在那里,整个代码被拆分到不同的单元中。
但这种划分是基于功能的,其中行为(功能)自然地分组到包中。按大小拆分可能会导致代码库笨拙;组合在一起可能很重要,更新可能会变得棘手(错误?)等等。这实际上会阻碍整体的可管理性。
如果一个模块感觉太大,很可能是捆绑在一起的功能太多,代码库应该在几个不同模块中。评估这一点没有简单的规则;设计库并不容易。考虑将一组函数分开以便它们拥有自己的 namespace 是否有意义可能会有所帮助。 †
然而,发布的示例还有另一个问题:它是一个类,但面向对象的机制与基本包导入混合在一起。这很复杂(如何/为什么将对象传递给在不是类的文件中定义的函数?),我不建议这样做。
设计良好的类是否会太大而无法很好地放入文件中?也许我猜,即使我没有见过这样的案例。通常,当代码库最终在 Perl 中的多个编译单元中被破坏时,这是因为功能的原因 -- 拥有多个类更合适。
但是,如果以某种方式最终只是大小成为问题,一个合理的方法可能是让多个文件每个都具有相同的 package
,并清楚地记录下来。
A.pm
package A;
use warnings;
use Strict;
use feature 'say';
# =======================================================
# NOTE: Class definition is given in multiple parts/files
# =======================================================
use A_part1;
use A_part2;
sub new { ... }
# perhaps more methods in this file
1;
A_part1.pm
package A;
# warnings,Strict,pragmas,etc
sub func1 { my ($self,@args) = @_; ... };
...
1;
和 A_part2.pm
等类似。然后照常使用
use A;
my $obj = A->new( ... );
$obj->func1(...);
请注意,这违反了关于文件名和包名之间关系的规则(约定)(A_part1.pm
vs package A;
);一方面,PerlCritic 会抱怨。‡但是,这里是故意这样做的,我不会担心。
但我认为实际上很少需要这样做。我宁愿期望,如果一个库看起来太大,它可能承担太多,应该重新设计成多个类。
† 但是如果确实有太多的函数属于同一个库,一旦文件被分解,考虑使用 require
将这些文件组合在一起。 >
‡Perl::Critic::Policy::Modules::requireFilenameR_342_11845@atchesPackage
,tl;dr:将方法组分成可管理的块。不要将每个方法都放入自己的文件中,也不要将一百万个方法放入一个文件中。拆分方式取决于任务、方法之间的关联方式以及您对全部编辑的容忍度。性能不是关键问题:可维护性才是。当性能成为问题时担心性能。
Benchmark
中的不确定性估计在该范围内。例如,参见 Steffen Mueller's wriTings about benchmarking 和他的 Dumbbench
模块。
您的基准测试显示每秒发生的事件不到 600 万次,而每秒发生的事件超过 600 万次。这在两种情况下都非常非常快。如果您添加了一个控件,例如一个普通的 sub { 1 }
,我想您会发现仅仅是测试行为是您的结果中最重要的因素。考虑到您还想测试所有其他情况,包括在没有导入的情况下从其源包调用方法、将所有内容作为普通子例程调用(没有方法分派)以及各种其他方式。您需要通过隔离不同的因素来梳理出真正重要的东西。
我有很多关于基准测试的讨论,其中代码没有按照我们认为的那样做,例如 WasTing time thinking about wasted time。由于您每秒运行如此多的迭代,我猜您实际上并没有测量任何真实的东西。例如,一旦 Perl 知道如何解析一个方法,它就不需要再次执行该工作。在您的基准测试开始之前,您对这个问题的所有疑问都已经发生了。
您有很多额外的代码(Readonly
、English
等)。除非这些东西是您要衡量的内容的一部分,否则请摆脱它们。我什至不确定他们正在做你认为他们正在做的事情。您也不需要从 Exporter 继承(因此与 @ISA
混在一起)。您只需要它的 import
例程,您可以将其导入。
以上是大佬教程为你收集整理的Perl OOP:在自己的模块中外包方法是个好主意吗全部内容,希望文章能够帮你解决Perl OOP:在自己的模块中外包方法是个好主意吗所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。