1

refを使用してデータ構造を再帰的にたどる再帰関数があります。ref が空の文字列を返す場合、コールバックが呼び出されます。私の問題は、関数によってスカラーとして扱われるハッシュ参照をデータ構造に格納する必要があることです。

本質的に、私が必要としているのは、このようなことをすることです。

    my %hash = fillHash();
    $hash{'abc'}{'def'} = \%hash;

参照ではなくスカラーとして扱われるような方法で \%hash を保存する方法があるかどうか疑問に思っていました。おそらく好き/

     $hash{'abc'}{'def'} = scalar \%hash;

データ構造の親ノードにリンクを追加する方法を探しているだけですが、それでも再帰的にそれを歩くことができます。

ありがとう

4

3 に答える 3

3

私が行ったことを使用して、値と構造を区別することができます。私はそれらを「間接配列」と呼んでいます(私の場合)。

あなたの場合、次のようになります。

 $hash{'abc'}{'def'} = scalar \\%hash;

ref( $hash{'abc'}{'def'} )'REF'、ご参考までに。そして、それを 2 回逆参照する必要があると判断できます。

$hash_ref = ${ $hash{'abc'}{'def'} };
于 2012-08-15T17:15:23.527 に答える
2

@MarkCanlasは、データを構造化する別の方法を検討するという彼の提案に正しい解決策があると思います. それがなければ、二重参照を取ることができます。

my $scalar_ref = \%hash;
$other_hash{abc}{def} = \$scalar_ref;

をチェックするrefと、元に戻り"REF"、別のことができます。

于 2012-08-15T17:15:16.940 に答える
1

まず、すべての参照は定義上スカラーであることを理解する必要があります。

必要なのは、どこでも参照として機能するものですが、ウォーキング関数内では機能します。それは、どんな種類の魔法の参照でも実際には達成できません。ウォーキング関数は、ロジックを追加する必要がある場所です。すでに見たものを追跡することができます:

my %h = (
    foo => "bar",
    inner => {
        foo => 42
    }
);

$h{inner}{parent} = \%h;

sub walk
{
    my ($h, $cb, $path, $seen) = @_;
    $path //= "";
    $seen //= {};
    $seen->{$h}=1;
    while(my ($k, $v) = each %$h) {
        if(ref($v)) {
            walk($v, $cb, "$path/$k", $seen) if !$seen->{$v};
        } else {
            $cb->($k, $v, "$path/$k");
        }
    }
}

walk(\%h, sub {
  my ($key, $value, $path) = @_;
  print "walker found $key ($path) => $value\n";
});

または、特別なキーなどの特定のキーを認識さparentせ、それらをスキップすることもできます。

于 2012-08-15T17:16:51.763 に答える