0

问题是我正在尝试创建一个散列散列,然后向每个散列添加更多元素。我正在从一个文件中读取,我正在匹配各种项目,我想将它们存储在不同的子哈希中 - ('Category','Item','Description','Score')。

稍后我需要将它们存储在CSV文件中,但目前我只是想打印它们,但我遇到了很多错误。

这是我的代码:

use strict;
use warnings;

my %MacroA = ('Category', 'Item', 'Description', 'Score');

open (my $file, '<', 'Layout.txt') or die $!;

while (my $line = <$file>) {

    if ($line  =~ /\b(layout)\b,/) {
        $MacroA{Category}++;
    }
    elsif ($line =~ /,([\w\s]+?),/) {
        $MacroA{Item}++;
    }
    elsif ($line =~ /,\b(\w+?.\d+?)\b,/g) {
        $MacroA{Desciption}++;
    }
    elsif ($line =~ /,\b(pass|fail)\b/) {
        $MacroA{Score}++;
    }
}

close $file;

foreach my $categories (keys %{ $MacroA{$Category}}) {
    print $categories, "\n";
}
foreach my $items (keys %{ $MacroA{$Item}}) {
    print $items, "\n";
}
foreach my $descriptions (keys %{ $MacroA{$Description}}) {
    print $descriptions, "\n";
}
foreach my $scores (keys %{ $MacroA{$Score}}) {
    print $scores, "\n";
}

我得到的错误:

Global symbol "$Category" requires explicit package name at MacroA.pl line 29.
Global symbol "$Item" requires explicit package name at MacroA.pl line 32.
Global symbol "$Description" requires explicit package name at MacroA.pl line 35.
Global symbol "$Score" requires explicit package name at MacroA.pl line 38.
Execution of MacroA.pl aborted due to compilation errors. . .
4

1 回答 1

7

您的问题只是代表了一些基本的误解,任何编程初学者最终都会努力克服这些误解。评论是完全正确的:当这种事情发生时,阅读你的错误并尝试使用一些好的教程或书籍来理解它们。我会尽力帮助你,虽然我不太清楚你想要达到什么目的。

你说你想创建一个“散列哈希”,但从你的代码的外观来看,你只是在创建一个计数散列,你可以在其中跟踪每个第一级“键”的次数(类别,项目等)出现在您正在读取的文件中。这不是现在的散列散列 -%MacroA目前仅包含一层散列。

第一个问题是您尝试使用要使用的键列表来定义散列。

my %MacroA = ('Category', 'Item', 'Description', 'Score');

您实际上是在尝试传递array您的密钥。如果你给一个散列一个数组,它会将第一个元素解释为它的键,第二个作为该键的值,第三个作为第二个键,依此类推。所以你最终会得到这个

%MacroA = (
    Category => Item,
    Description => Score
)

要仅为一级键初始化散列,您可以为每个键指定初始计数 0:

my %MacroA = ('Category', 0, 'Item', 0, 'Description', 0, 'Score', 0);

这通常用箭头符号写,=>以使事情更清楚

my %MacroA = ('Category' => 0, 'Item' => 0, 'Description' => 0, 'Score', 0);

要初始化第二级键的哈希,您可以这样做(正如您在评论中正确建议的那样):

my %MacroA = ('Category' => {}, 'Item' => {}, 'Description' => {}, 'Score', {});

实际上,您甚至不需要将散列初始化为具有空值的键,因为 Perl 将在您第一次使用时使用自动激活来初始化一个空键。所以你真正需要做的就是像这样初始化散列变量

my %MacroA;

我将在这里猜测一下,并假设您打算将类别、描述等作为您的第一级键,然后将您在文件中找到的任何内容作为第二级键。我想你想计算第二级键出现的次数。

目前,您的哈希正在跟踪 Category、Item... 键,因为您正在递增使用这些键存储的值:

$MacroA{Category}++;

因为您的正则表达式匹配将返回它们匹配到标量变量的任何内容$1,您可以使用它来增加第二级哈希,如下所示:

$MacroA{Category}->{$1}++;

最后,在打印出您的计数时,您犯了一个简单的错误,即使用变量引用您的键字符串:

$MacroA{$Category}

您可能打算为每个第一级键使用一个字符串:

$MacroA{'Category'};

Perl 认为您正在尝试使用未定义的变量$Category,因此会抛出您遇到的错误。

最后,如果您Dumper在代码中的某些点打印数据结构的格式化日志,它肯定会帮助您理解。只需使用代码

use Data::Dumper;
print Dumper(\%MacroA);

在脚本中的任何时间点查看该%MacroA时间点的结构。

于 2012-11-26T15:58:35.817 回答