perl引用填充它的范围之外的哈希(直方图)

时间:2014-11-24 23:28:46

标签: perl hashmap histogram

:大家好。 我试图将这些数据解析为直方图。 当我解析文件并将我得到的值和很小的数据集子串出来时。

#!/usr/bin/perl
use strict ;
use warnings ;
open (my $fh_tmp, '<', "/tmp/gap_output") ;
while(<$fh_tmp>) {
    my ($date, $time, $host) = split ;
    my $host_length = 12;
    my $time_length = 5;
    my $host_slice = substr $host, 0 , $host_length ;
    my $time_slice = substr $time, 0 , $time_length ;
    print "$host_slice, $time_slice\n" ;

    }

看 - 这很棒。

trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 03:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 07:10
trip7829host, 03:10
trip7829host, 03:10
trip7830host, 07:30
trip7830host, 07:30
trip7831host, 07:30
trip7831host, 07:30
trip7832host, 07:30

最终我需要得到的是这样的东西。 uniqe主机,唯一时间和每分钟发生此错误(显示为n0t)的次数。 现在发生在我身上 - 我可能需要一个多级哈希(ugg)。直到那个问题为止 - 我甚至无法填充常规哈希值。

trip7829host, 03:10 10 ##########
trip7829host, 07:10 10 ##########
trip7830host, 07:30 2  ##
trip7831host, 07:30 2  ##
trip7832host, 07:30 1  #

我尝试使用一堆我和我的。虽然并不重要。 我有点想到,一旦填充了gap_ids,我就不会有 再次声明它 - 它将生活在while循环的范围之外 - 但它没有,因为严格要求我再次申报。我试过导入 这些价值观与'我们'。

casper@trip0170pap:~/walt/historgram$ cat gap_histgram
#!/usr/bin/perl
use strict ;
use warnings ;
open (my $fh_tmp, '<', "/tmp/gap_output") ;
while(<$fh_tmp>) {
    my ($date, $time, $host) = split ;
    our %gap_ids ;
    my $host_length = 12;
    my $time_length = 5;
    my $host_slice = substr $host, 0 , $host_length ;
    my $time_slice = substr $time, 0 , $time_length ;
    our ($key, $value) = ($host_slice, $time_slice) ;

    #print "$key , $value\n"  ;
    $gap_ids{$key} = $value ;
    }

while(($key, $value) =each %gap_ids) {
    printf ("%-40s %-6s", $key, $value) ;
    for (my $index =1; $index <= $value; $index++) {
    print "#" ;
    }
print "\n" ;
}



-rwxr-xr-x 1 casper casper 643 Nov 24 16:03 gap_histgram*
casper@trip0170host:~/walt/historgram$ ./gap_histgram
Variable "$key" is not imported at ./gap_histgram line 18.
Variable "$value" is not imported at ./gap_histgram line 18.
Variable "%gap_ids" is not imported at ./gap_histgram line 18.
Variable "$key" is not imported at ./gap_histgram line 19.
Variable "$value" is not imported at ./gap_histgram line 19.
Variable "$value" is not imported at ./gap_histgram line 20.
Global symbol "$key" requires explicit package name at ./gap_histgram line 18.
Global symbol "$value" requires explicit package name at ./gap_histgram line 18.
Global symbol "%gap_ids" requires explicit package name at ./gap_histgram line 18.
Global symbol "$key" requires explicit package name at ./gap_histgram line 19.
Global symbol "$value" requires explicit package name at ./gap_histgram line 19.
Global symbol "$value" requires explicit package name at ./gap_histgram line 20.
Execution of ./gap_histgram aborted due to compilation errors.

这些错误只是神秘莫测。

2 个答案:

答案 0 :(得分:1)

是否有任何理由必须使用全局变量声明

通过在第一个while循环之外声明%gap_ids,您的问题似乎是可以解决的。这将在第二个while循环中访问哈希

所以你的代码应该是:

#!/usr/bin/perl
use strict ;
use warnings ;
open (my $fh_tmp, '<', "/tmp/gap_output") ;

my %gap_ids;

while(<$fh_tmp>) {
    my ($date, $time, $host) = split ;
    our %gap_ids ;
    my $host_length = 12;
    my $time_length = 5;
    my $host_slice = substr $host, 0 , $host_length ;
    my $time_slice = substr $time, 0 , $time_length ;
    my ($key, $value) = ($host_slice, $time_slice) ;

    #print "$key , $value\n"  ;
    $gap_ids{$key} = $value ;
}

while(my ($key, $value) = each %gap_ids) {
    printf ("%-40s %-6s", $key, $value) ;
    for (my $index =1; $index <= $value; $index++) {
        print "#" ;
    }
print "\n" ;
}

请注意,我已将%gap_ids移位。并在第一个循环中更改我们的($ key,$ value)。

答案 1 :(得分:1)

my声明一个变量,它是里面的花括号的局部变量。

use strict;

my $visible_to_the_whole_file = 7;

{
   my $only_visible_in_here = 21;
}

print "$visible_to_whole_file\n";   # works ok

print "$only_visible_in_here\n";  # WILL FAIL, there is no variable any more.

您可以完全忽略our,因为您没有在任何地方使用package,但它的范围也是大括号。一对花括号称为“块”。

鉴于此,您可以了解为什么需要声明变量,包括{/ 1}} 之外的两个while循环中,如果您希望代码看到值内部两个while循环。 (假设%gap_ids

use strict

如果您希望变量在两个块中都可见,则可以执行此操作。

{
    my $some_variable = 21;
}
{
    print $some_variable;  # will FAIL, is no longer visible
}

更重要的是,如果你在两个不同的块中my $some_variable; { $some_variable = 21; } { print $some_variable; # yay, it's still 21! } 变量,你最终会得到两个不同的变量。

my

希望这有用!