将怪物Perl模块重构为子模块的好方法是什么?

Dav*_*oby 5 perl perl-module

我有一个项目的Perl模块.我可能有十几个程序挂起来,其中很多都是垃圾.我以前没有和DBI花费太多个人时间,所以这部分是可以修复的,但最重要的是它很大.字面上2KLOCs.

很容易将这个函数(我们称之为Dumb.pm)分解为单独的模块(Dumb :: FormTools,Dumb :: Database等),除了我说的,有很多程序已经使用了Dumb; "

我想通过Dumb导出Dumb :: Database的可导出函数,而不必一遍又一遍地改变它:

sub my_dumb_function { return Dumb::Database::my_dumb_function( @_ ) ; }
Run Code Online (Sandbox Code Playgroud)

并不是说我高于那个.只是这似乎是处理问题的愚蠢和不雅的方式.我曾经使用过"不要不知道更好"的借口,而且一次真的比你得到的还要多.救命?

bri*_*foy 7

由于不同的代码库需要不同的策略,因此很难给出具体的建议.我重构一个具有500行子程序的模块,而不是一个具有小子程序和大量重复代码的模块.如果我也需要更改界面,那么有不同的策略.

  1. 让一切都进入源代码管理.您需要保留原始版本和中间版本.
  2. 如果您还没有测试套件,请写一个.尽可能高地获得测试覆盖率.此测试套件是在未来版本,错误和所有版本中保留相同行为的基线.您可能会遇到一个依赖于原始模块中的错误的程序.
  3. 开始乱砍.在每个步骤中,检查其余部分是否仍然通过原始测试,并且发布的接口仍然会导致相同的行为.

我认为你的实际问题是"如何导出到加载Dumb的原始模块?".您可以提供import使用Exporter import_to_level方法的自己的例程.您可以导入到比加载您的直接级别更高的级别.因此Dumb::Database import可以将其导出加载到加载的命名空间中,Dumb即使它Dumb是加载的Dumb::Database.

  • 我不明白为什么你推荐`import_to_level`.`Dumb`将成为一个向后兼容模块,直到`使用Dumb;`可以被特定程序所需的各个模块替换.为什么要在每个新模块中编写一个自定义`import`,当库存`import`允许`Dumb`重新导出从新模块导入的函数时,必须决定导出到哪个级别? (2认同)

mac*_*ail 3

不确定您当前如何使用它(当前是否导出方法?),但您可以设置新的子模块以允许导入它们的函数(使用 Exporter),然后让原始模块显式导入现在损坏的模块出件。就像是:

package Dumb;

use Dumb::Database qw(my_dumb_function);

1;

package Dumb::Database;

use base qw(Exporter);

our @EXPORT_OK = qw(my_dumb_function);

sub my_dumb_function { 1; }

1;
Run Code Online (Sandbox Code Playgroud)