我的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
答案 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 *_;
)。