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

时间:2017-03-16 13:19:30

标签: perl perl-module separation-of-concerns

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

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

核心功能是使用嵌套在while (<>)循环中的嵌套(或命名为作用域)模式匹配:

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

...在关闭大括号之前有超过200行。

我觉得只需从ARGV阅读就会超过 Do one thing and do it well 规则。当我搜索网络时,我发现没有任何内容明确地说明 反对从模块中的ARGV读取,但也许我的搜索模式很差。 [1] [2]

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

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

2 个答案:

答案 0 :(得分:4)

你可以让你的函数不知道<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

答案 1 :(得分:3)

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

另外,不要打电话给你的来电者$_$_经常与其他变量(会产生深远影响)和常量(这会导致代码失败)混淆。使用您自己的词法范围变量(或者至少首先添加local *_;)。