如何在perl中存储一个本身不是引用的引用

时间:2012-08-15 16:55:00

标签: perl

我有一个递归函数,使用ref递归地向下走数据结构。如果ref返回一个空字符串,则调用一个回调。我的问题是我需要在我的数据结构中存储一个hash-ref,它将被我的函数视为标量。

从本质上讲,我需要的是做这样的事情;

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

我想知道是否存在以某种方式存储\%hash的方式,它将被视为标量而不是引用。可能喜欢/

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

我只是想找到一种方法来添加一个链接到我的数据结构的父节点,但仍然可以递归地遍历它。

由于

3 个答案:

答案 0 :(得分:3)

您可以使用我所做的来区分值与结构,我称之为“间接数组”(在我的情况下)。

在你的情况下,它看起来像这样:

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

ref( $hash{'abc'}{'def'} )'REF',以防你想知道。然后,您可以决定需要取消引用它两次:

$hash_ref = ${ $hash{'abc'}{'def'} };

答案 1 :(得分:2)

我认为@MarkCanlas在他的建议中有正确的解决方案,可以考虑采用不同的方式来构建数据。除此之外,你可以采取双重参考。

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

现在,当您检查ref时,您将返回"REF"并可以执行其他操作。

答案 2 :(得分: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之类的某些键识别为特殊并跳过它们。