2

我有一个脚本,我想将其转换为模块并从 Perl 脚本调用它的函数,就像我现在对 CPAN 模块所做的那样。我的问题是其他人将如何设计模块,我想知道如何进行,因为我以前从未编写过模块。现在编写的脚本执行以下操作:

1) 使用 am in house 模块设置日志记录到数据库 2) 使用 DBI 建立与数据库的连接 3) 使用 Net::SFTP:Foreign 从远程服务器获取文件 4) 处理每个文件中的用户并将数据添加到数据库

该脚本当前采用命令行选项来使用 Getopt::Long 覆盖默认值。

每个文件都是一个管道分隔的用户数据集合,大约 4000 行,如果用户在我们的 LDAP 目录中有一个条目,它会进入数据库。

更重要的是:我应该如何设计我的模块?是否应该将我的脚本当前所做的所有内容都移到模块中,或者是否有一些最好留在脚本中的东西。例如,我正在考虑设计我的模块,所以它会被这样调用:

use MyModule;

$obj = MyModule->new; // possibly pass some arguments

$obj->setupLogging;

$obj->connectToDB;

$obj->fetchFiles;

$obj->processUsers;

这将使脚本保持整洁,但这是模块的最佳主意吗?我正在考虑让脚本检索文件,然后将路径传递给模块进行处理。谢谢

4

2 回答 2

2

我认为最有用的问题是“这段代码中有哪些可以被多个脚本使用?” 整个事情肯定不会。我很少创建 perl 模块,直到我发现自己不止一次地编写同一个子例程。

在那个阶段,我通常将它转储到一个名为“Utility.pm”的东西中,直到收集到足够的代码,模式(实际上不是四种意义上的)开始建议什么属于具有明确定义的职责的模块。

您需要考虑的另一件事是您的模块是要表示一个对象类还是要成为库子例程的集合。

在您的示例中,我可以看到属于外部模块的日志记录和数据库连接管理(尽管我可能会使用 DBI)。

但是将所有内容放在那里只会给您留下一个名为“MyModule::DoStuff”的五行脚本,这没什么用处。

大多数时候 ;)

于 2012-05-08T14:38:56.423 回答
1

“这是模块的最佳主意吗?我正在考虑让脚本检索文件,然后将路径传递给模块进行处理。”

在我看来,它是一个不错的设计。我也同意您不应该在模块中硬编码路径(或 URL),但我对“让脚本检索文件然后将路径传递给模块进行处理”的含义有点困惑:你的意思是,脚本会将它们写入磁盘吗?为什么要这样做?相反,如果有意义,请fetchFile(URL)检索单个文件并返回适合提交到的引用/句柄/对象processUsers,因此逻辑如下:

my @FileUrls = ( ... );

foreach (@FileUrls) {
    my $file = $obj->fetchFile($_);
    $obj->processUsers($file);
}

虽然,如果 fetchFile 的目的只是为了获取一些原始文本,您可能希望使该函数独立于数据库类——或者是脚本的一部分,或者是另一个模块。

如果您想要写入磁盘的原因是您不希望一次将整个文件加载到内存中,您可能需要调整所有内容以处理文件块,这样您就可以拥有一种用于获取文件的对象通过套接字并在将块读取到另一种对象(添加到数据库的过程)时输出块。在这种情况下:

my $db = DBmodule->new(...);
my $netfiles = NetworkFileReader->new(...)

foreach (@FileUrls) {
    $netfiles->connect($_);
    $db->newfile();  # initialize/reset
    while (my $chunk = $netfiles->more()) {
        $db->process($chunk);
    }
    $db->complete();
    $netfiles->close();
}

或者,如果您认为它更合适且不太可能用于通用目的,则将块读取合并到 db 类中。

于 2012-05-08T15:21:32.587 回答