0

問題は、ハッシュのハッシュを作成してから、各ハッシュにさらに要素を追加しようとしていることです。ファイルから読み取っていて、さまざまなアイテムを照合していて、それらを別のサブハッシュ (「カテゴリ」、「アイテム」、「説明」、「スコア」) に保存したいと考えています。

後で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。現時点では、1 レベルのハッシュのみで構成されています。

最初の問題は、使用したいキーのリストを使用してハッシュを定義しようとしていることです。

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

あなたは実際にあなたの鍵を渡そうとしていarrayます。ハッシュに配列を指定すると、最初の要素がそのキーとして解釈され、2 番目の要素がそのキーの値として解釈され、3 番目の要素が 2 番目のキーとして解釈されます。だからあなたはこれで終わるでしょう

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

キーの 1 レベルのみのハッシュを初期化するには、各キーに初期カウント 0 を指定できます。

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

これは通常=>、物事をより明確にするために矢印記号で書かれています

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

2番目のレベルのキーのハッシュを初期化するには、これを行うことができます(コメントで正しく提案したように):

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

実際、Perl は空のキーを最初に使用するときに autovivification を使用して空のキーを初期化するため、ハッシュを空の値のキーに初期化する必要さえありません。したがって、実際に行う必要があるのは、ハッシュ変数を次のように初期化することだけです

my %MacroA;

ここで推測して、Category、Description などをキーの第 1 レベルとして使用し、ファイル内で見つかったものをキーの第 2 レベルとして使用するつもりだったと仮定します。第 2 レベルのキーが発生した回数を数えたいと思います。

現時点では、これらのキーで格納されている値をインクリメントしているため、ハッシュは Category、Item... キーを追跡しています。

$MacroA{Category}++;

正規表現の一致は、一致したものをスカラー変数に返すため$1、それを使用して、次のようにハッシュの第 2 レベルをインクリメントできます。

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

最後に、カウントを出力するときに、キー文字列を変数で参照するという単純な間違いを犯します。

$MacroA{$Category}

おそらく、最初のレベルのキーのそれぞれに文字列を使用するつもりだった場所:

$MacroA{'Category'};

Perl は、呼び出された未定義の変数を使用しようとしていると$Category判断し、エラーをスローします。

Dumper最後に、コードの特定のポイントでデータ構造のフォーマットされたログを出力すると、間違いなく理解に役立ちます。コードを使うだけ

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

スクリプトの任意の時点で、%MacroAその時点での構造を表示します。

于 2012-11-26T15:58:35.817 に答える