我应该在自己的 perl 模块中读取 ARGV 吗

should I read from ARGV in own perl module

我的 Perl 从(多个)日志文件中提取和处理数据,目前正在处理 @ARGV 中的所有文件。

这个脚本最重要的部分是日志解码本身,它包含了很多关于日志文件格式的知识。这个来自日志的转换部分(实际上是一个哈希数组)已被证明是变化的主题(随着日志格式的发展),并且是进一步发展的基础处理 个步骤:解码后的记录通常有特定的问题要回答,这在 Perl 中做得最好,这就是为什么我想把它做成一个模块。

核心功能是使用嵌套(或将其命名为 scoped)模式匹配 while (<>) 循环:

while (<ARGV>) {
    $totalLines ++;
    if (m/^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d) L(\d) (.+)/) {
        my $time = ;
        my $line = ;
        my $event = ;
        if ($event =~ m/^connect: (.+)$/) {
            $pendings{$line}{station} = ;
            ...

...右大括号前有 200 多行。

我有一种感觉,仅仅从 ARGV 读取会超出 Do one thing and do it well 规则。当我在网上搜索时,我没有发现任何明确说明 foragainst reading from ARGV in module,但也许是我的搜索模式只是很穷。 [1] [2]

(如何)我应该重新构建我的解码以将其放入模块?
...或者我应该改变我的对此有何感想?


[1] perltrap - perldoc.perl.org
[2] perlmodstyle - perldoc.perl.org

您可以让您的函数不知道 <ARGV> 迭代器逻辑,

sub foo {
    my ($iter) = @_;

    # `defined()` should be used explicitly unlike `while (<ARGV>)`
    while (defined (my $line = $iter->())) {
        # if ..
    }
}

foo(sub{ scalar <ARGV> }); # force scalar context; one line/record per call

我会这样写,它接受任何文件句柄。然后,您可以使用 \*ARGV 作为参数。

另外,不要破坏来电者的$_$_ 通常是其他变量的别名(这会产生深远的影响)和常量(这会导致您的代码失败)。请改用您自己的词法范围变量(或至少先添加 local *_;)。