将一个巨大的Perl模块重构为子模块的好方法是什么?

14ifxucb  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(159)

我有一个项目的Perl模块。我可能有十几个程序挂在上面,很多都是垃圾。我以前没有花太多的私人时间在DBI上,所以这部分是可以修复的,但重要的是它很大。字面上是2KLOC。
将这个函数(我们称之为Dumb.pm)分解为单独的模块(Dumb::FormTools、Dumb::Database等)是很容易的,除非,正如我所说的,有很多程序已经在“使用Dumb ;'
我想通过Dumb导出Dumb::Database的可导出函数,而不必一遍又一遍地进行修改:

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

不是说我不屑于此。只是这看起来像是处理问题的愚蠢和不优雅的方式。我用了一次“不知道更好”的借口,一次真的比你得到的多。帮助?

vmpqdwk3

vmpqdwk31#

很难给予你具体的建议,因为不同的代码库需要不同的策略。我重构了一个包含500行子程序的模块,而不是一个包含小子程序和大量重复代码的模块。如果我还需要改变接口,也有不同的策略。
1.把所有东西都放到源代码管理中。你需要保留原始版本和中间版本。
1.如果你还没有一个测试套件,那就写一个。尽可能地覆盖更多的测试。这个测试套件是在未来版本中保持相同行为、bug和所有的基线。你可能会遇到一个依赖于原始模块中bug的程序。
1.在每一步中,检查其余部分是否仍然通过了最初的测试,并且发布的接口是否仍然产生相同的行为。
我想你真正的问题是“如何导出到加载Dumb的原始模块?"。您可以提供自己的import例程,该例程使用Exporter的import_to_level方法。您可以导入到比加载您的直接模块更高的级别。Dumb::Databaseimport因此可以将其导出加载到加载Dumb的命名空间中,即使它'Dumb,它加载Dumb::Database

9lowa7mx

9lowa7mx2#

不确定你现在是如何使用它的(它现在导出方法吗?),但是你可以设置新的子模块,允许你导入它们的函数(使用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;
9gm1akwq

9gm1akwq3#

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

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;

相关问题