程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Perl OOP:在自己的模块中外包方法是个好主意吗大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_801_0@如何解决Perl OOP:在自己的模块中外包方法是个好主意吗? 开发过程中遇到Perl OOP:在自己的模块中外包方法是个好主意吗的问题如何解决?下面主要结合日常开发的经验,给出你关于Perl OOP:在自己的模块中外包方法是个好主意吗的解决方法建议,希望对你解决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 快。

  1. 为什么 login2 比 login 快?
  2. 将每个方法放在自己的模块中是个好主意吗?
    1. 有更好的方法吗?

我期待着评论。

@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:将方法组分成可管理的块。不要将每个方法都放入自己的文件中,也不要将一百万个方法放入一个文件中。拆分方式取决于任务、方法之间的关联方式以及您对全部编辑的容忍度。性能不是关键问题:可维护性才是。当性能成为问题时担心性能。


您在测试中看到大约 6% 的差异,但需要虑以下几点:

  • Benchmark 中的不确定性估计在该范围内。例如,参见 Steffen Mueller's wriTings about benchmarking 和他的 Dumbbench 模块。

  • 您的基准测试显示每秒发生的事件不到 600 万次,而每秒发生的事件超过 600 万次。这在两种情况下都非常非常快。如果您添加了一个控件,例如一个普通的 sub { 1 },我想您会发现仅仅是测试行为是您的结果中最重要的因素。虑到您还想测试所有其他情况,包括在没有导入的情况下从其源包调用方法、将所有内容作为普通子例程调用(没有方法分派)以及各种其他方式。您需要通过隔离不同的因素来梳理出真正重要的东西。

  • 我有很多关于基准测试的讨论,其中代码没有按照我们认为的那样做,例如 WasTing time thinking about wasted time。由于您每秒运行如此多的迭代,我猜您实际上并没有测量任何真实的东西。例如,一旦 Perl 知道如何解析一个方法,它就不需要再次执行该工作。在您的基准测试开始之前,您对这个问题的所有疑问都已经发生了。

  • 您有很多额外的代码(ReadonlyEnglish 等)。除非这些东西是您要衡量的内容的一部分,否则请摆脱它们。我什至不确定他们正在做你认为他们正在做的事情。您也不需要从 Exporter 继承(因此与 @ISA 混在一起)。您只需要它的 import 例程,您可以将其导入。

大佬总结

以上是大佬教程为你收集整理的Perl OOP:在自己的模块中外包方法是个好主意吗全部内容,希望文章能够帮你解决Perl OOP:在自己的模块中外包方法是个好主意吗所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。