什么';将monster Perl模块重构为子模块的好方法是什么?
我有一个项目的Perl模块。我可能有十几个程序挂在上面,很多都是垃圾。我以前没有与DBI有过太多亲密的私人关系,所以这部分是可以修复的,但重要的是它是大的。从字面上说是两个洛克斯 很容易将这个函数(我们称之为Dumb.pm)分解成单独的模块(Dumb::FormTools、Dumb::Database等),但正如我所说,有很多程序已经“使用Dumb;” 我想通过Dumb导出Dumb::Database的可导出函数,而不必反复修改:什么';将monster Perl模块重构为子模块的好方法是什么?,perl,perl-module,Perl,Perl Module,我有一个项目的Perl模块。我可能有十几个程序挂在上面,很多都是垃圾。我以前没有与DBI有过太多亲密的私人关系,所以这部分是可以修复的,但重要的是它是大的。从字面上说是两个洛克斯 很容易将这个函数(我们称之为Dumb.pm)分解成单独的模块(Dumb::FormTools、Dumb::Database等),但正如我所说,有很多程序已经“使用Dumb;” 我想通过Dumb导出Dumb::Database的可导出函数,而不必反复修改: sub my_dumb_function { return Du
sub my_dumb_function { return Dumb::Database::my_dumb_function( @_ ) ; }
我并不是高高在上。只是这似乎是处理问题的愚蠢和不雅的方式。我用过一次“不知道没有更好”的借口,一次真的比你得到的更多。帮助?不确定您当前如何使用它(它当前是否导出方法?),但您可以设置新的子模块以允许您导入其功能(使用导出器),然后让原始模块显式导入现在分解的部分。比如:
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;
很难给出具体的建议,因为不同的代码库需要不同的策略。我重构一个有500行子程序的模块,与重构一个有小子程序和大量重复代码的模块不同。如果我也需要改变界面,有不同的策略
不过,我认为您的实际问题是“如何导出到加载Dumb的原始模块?”。您可以提供自己的
import
例程,该例程使用Exporter的import\u to_level
方法。您可以导入到比加载您的即时级别更高的级别。因此,Dumb::Database
import
可以将其导出加载到加载Dumb
的命名空间中,即使加载Dumb::Database
的是Dumb
我假设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
标记。您必须手动定义它(在每个子模块中)
另一方面,如果子模块没有
@EXPORT\u OK
功能,那么您可以跳过:all
标记,只说使用Dumb::submodule
您可能还想研究一下我没有时间写一个正确的答案,但是您可以在Dumb
中使用自定义的import
函数,将对import
的调用路由到各个子模块。只有2k LOC?哇,一个很好的小模块!;)。。。然后是我在上一份工作中继承的14K怪物,有7K个提交日志…*我的dumb\u函数=\&dumb::Database::my\u dumb\u函数
这几乎就是Exporter的功能。我只有使用“use Exporter qw(import);”才能让它工作,但这意味着我能够让它工作。非常感谢。您还可以从Exporter继承,这就是我的意思。对不起,我已经更正了。我不明白你为什么建议将导入到\u级别Dumb
将成为向后兼容模块,直到使用Dumb代码>可以由特定程序需要的单个模块替换。当库存import
允许Dumb
重新导出从新模块导入的功能时,您为什么要在每个新模块中编写自定义import
,以决定导出到哪个级别?如果Dumb
需要拆分为单独的模块,并且顶级程序仍然希望获得只需使用Dumb
就可以从这些单独的模块导出,这样您就不想在Dumb
中导入了。但是,如果OP想做其他事情,我不推荐它作为解决方案。这里有很多方法。你的答案是正确的,但我认为你必须导入Dumb,这样你才能将相同的东西导出到更高的层次,这是不雅的。正如我理解OP的问题,他有一个巨大的模块,可以做很多不同的事情。他希望自己使用了单独的模块,这样脚本就可以只加载实际使用的模块。但他不想追踪每一个说使用Dumb
的程序,并修复它以导入正确的模块。他需要一个Dumb.pm与现有的导出进行向后兼容,这样他就可以逐步修复那些使用Dumb
的程序,使其只使用实际需要的模块。这是一种看待问题的方法,但我认为这是在添加一些不存在问题的假设。我没有做出和你一样的假设。这些可能是有道理的,但只有他才能澄清他想要做什么,以及哪个答案更适合他
our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ] );
# or, for a module that doesn't export anything by default:
our %EXPORT_TAGS = ( all => \@EXPORT_OK );