gpt4 book ai didi

perl - 皮条客我的 Perl 代码

转载 作者:行者123 更新时间:2023-12-03 18:18:30 25 4
gpt4 key购买 nike

我是一位经验丰富的开发人员,但不是 Perl。我通常学习 Perl 来破解脚本,然后我又忘记了,直到下一次。因此,我正在寻求专业人士的建议。

这一次,我正在构建一系列数据分析脚本。粗略简化,程序结构是这样的:

01 my $config_var = 999;

03 my $result_var = 0;

05 foreach my $file (@files) {
06 open(my $fh, $file);
07 while (<$fh>) {
08 &analyzeLine($_);
09 }
10 }

12 print "$result_var\n";

14 sub analyzeLine ($) {
15 my $line = shift(@_);
16 $result_var = $result_var + calculatedStuff;
17 }

在现实生活中,大约有六种不同的 config_var s 和 result_var s。

这些脚本的主要区别在于分配给 config_var 的值。 s。主循环在每种情况下都是相同的, analyzeLine()将基本相同,但可能会有一些小的变化。

我可以通过制作 N 份这段代码来实现我的目的,在这里和那里做些小改动;但这严重违反了良好设计的各种规则。理想情况下,我想编写一系列仅包含一组配置变量初始化的脚本,然后是
do theCommonStuff;

请注意 config_var (及其同级)必须可用于公共(public)代码, result_var 也必须如此。及其相似物, analyzeLine()做一些计算。

我应该将我的“通用”代码打包到一个模块中吗?创建一个类(class)?使用全局变量?

虽然不完全编写高尔夫代码,但我正在寻找一个简单、紧凑的解决方案,它允许我干燥并仅为差异编写代码。我想我宁愿不将代码从包含所有配置的巨大表中删除,当然也不会将其调整为使用数据库。

期待您的建议,谢谢!

更新

既然有人问,这里是真正的 analyzeLine :
# Update stats with time and call data in one line.
sub processLine ($) {
my $line = shift(@_);
return unless $line =~ m/$log_match/;
# print "$1 $2\n";
my ($minute, $function) = ($1, $2);
$startMinute = $minute if not $startMinute;
$endMinute = $minute;
if ($minute eq $currentMinute) {
$minuteCount = $minuteCount + 1;
} else {
if ($minuteCount > $topMinuteCount) {
$topMinute = $currentMinute;
$topMinuteCount = $minuteCount;
printf ("%40s %s : %d\n", '', $topMinute, $topMinuteCount);
}
$totalMinutes = $totalMinutes + 1;
$totalCount = $totalCount + $minuteCount;
$currentMinute = $minute;
$minuteCount = 1;
}
}

由于这些变量在很大程度上是相互依赖的,我认为单独计算的功能解决方案是不切实际的。我为误导人们道歉。

最佳答案

两条评论:首先,不要发布行号,因为它们会使复制、粘贴和编辑变得比必要的更加困难。二、不要使用&func()调用一个子。见 perldoc perlsub :

A subroutine may be called using an explicit & prefix. The & is optional in modern Perl, ... Not only does the & form make the argument list optional, it also disables any prototype checking on arguments you do provide.



简而言之,使用 &除非您知道自己在做什么以及为什么要这样做,否则可能会令人惊讶。

另外, don't use prototypes在 Perl 中。它们与其他语言的原型(prototype)不同,同样可以有 非常除非您知道自己在做什么,否则会产生令人惊讶的效果。

不要忘记检查 open 等系统调用的返回值.使用 autodie与现代 perl s。

对于您的特定问题,请在哈希中收集所有配置变量。将该哈希传递给 analyzeLine .
#!/usr/bin/perl

use warnings; use strict;
use autodie;

my %config = (
frobnicate => 'yes',
machinate => 'no',
);

my $result;
$result += analyze_file(\%config, $_) for @ARGV;

print "Result = $result\n";

sub analyze_file {
my ($config, $file) = @_;

my $result;

open my $fh, '<', $file;
while ( my $line = <$fh> ) {
$result += analyze_line($config, $line);
}

close $fh;

return $result;
}

sub analyze_line {
my ($line) = @_;
return length $line;
}

当然,你会注意到 $config正在到处传递,这意味着您可能希望将其转换为 OO 解决方案:
#!/usr/bin/perl

package My::Analyzer;

use strict; use warnings;

use base 'Class::Accessor::Faster';

__PACKAGE__->follow_best_practice;
__PACKAGE__->mk_accessors( qw( analyzer frobnicate machinate ) );

sub analyze_file {
my $self = shift;
my ($file) = @_;

my $result;

open my $fh, '<', $file;
while ( my $line = <$fh> ) {
$result += $self->analyze_line($line);
}

close $fh;

return $result;
}

sub analyze_line {
my $self = shift;
my ($line) = @_;
return $self->get_analyzer->($line);
}

package main;

use warnings; use strict;
use autodie;

my $x = My::Analyzer->new;

$x->set_analyzer(sub {
my $length; $length += length $_ for @_; return $length;
});
$x->set_frobnicate('yes');
$x->set_machinate('no');


my $result;
$result += $x->analyze_file($_) for @ARGV;

print "Result = $result\n";

关于perl - 皮条客我的 Perl 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2093531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com