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

时间:2010-01-28 17:42:29

标签: perl perl-module

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

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

我想通过Dumb导出Dumb :: Database的可导出函数,而不必反复出现这种变化:

sub my_dumb_function { return Dumb::Database::my_dumb_function( @_ ) ; }

不是我高于那个。只是这似乎是处理问题的愚蠢和不雅的方式。我曾经使用过“不要不知道更好”的借口,而且一次真的比你得到的还要多。帮助

4 个答案:

答案 0 :(得分:7)

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

  1. 将所有内容都放入源代码管理中。您需要保留原始版本和中间版本。
  2. 如果您还没有测试套件,请写一个。尽可能高地获得测试覆盖率。此测试套件是在未来版本,错误和所有版本中保留相同行为的基线。您可能会遇到一个依赖于原始模块中的错误的程序。
  3. 开始乱砍。在每个步骤中,检查其余部分是否仍然通过原始测试,并且发布的界面仍然会导致相同的行为。
  4. 我认为你的实际问题是“如何导出到加载Dumb的原始模块?”。您可以提供使用Exporter的import方法的import_to_level例程。您可以导入到比加载您的直接级别更高的级别。因此Dumb::Database import可以将其导出加载到加载Dumb的命名空间中,即使它是加载Dumb的{​​{1}}。

答案 1 :(得分: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;

答案 2 :(得分:3)

我认为Dumb.pm目前使用Exporter。假设您不想重命名函数(只需将它们拆分为单独的模块),您应该能够保留现有的@EXPORT定义,从子模块导入所有内容,然后只需重新导出函数。 / p>

package Dumb;
use Dumb::FormTools ':all';
use Dumb::Database  ':all';

use Exporter 'import';

our @EXPORT = ...;    # Unchanged from original version
our @EXPORT_OK = ...; # Unchanged from original version

1;

默认情况下未定义:all标记。您必须手动定义它(在每个子模块中)。

our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ] );
# or, for a module that doesn't export anything by default:
our %EXPORT_TAGS = ( all => \@EXPORT_OK );

另一方面,如果子模块没有@EXPORT_OK个功能,那么您可以跳过:all标记,然后说出use Dumb::Submodule;

答案 3 :(得分:1)

您可能还想查看Sub::Exporter