0

我有一个深度嵌套结构的哈希。嵌套的级别事先是未知的。但是每个级别都有两个属性“实例”和另一个“依赖项”散列。所以它是一种看起来像递归的散列。

my $HASH = {
    "top"=> {
        "instance" => "top_instance",
        "dependencies" => {
            "sub_block1" => {
                "instance" => "sub_block1_instance",
                "dependencies" => {}
            },
            "sub_block2" => {
                "instance" => "sub_block2_instance",
                "dependencies" => {
                    "sub_block3" => {
                        "instance" => "sub_block3_instance",
                        "dependencies" => {}
                    }
                }
            }
        }
    }
};

我有一个子例程,它接受用户定义的字符串并从指定的层次结构级别返回哈希的内部片段。

例如,如果用户指定“sub_block2”,则子例程应返回此哈希:

{
    "sub_block2" => {
        "instance" => "sub_block2_instance",
        "dependencies" => {
            "sub_block3" => {
                "instance" => "sub_block3_instance",
                "dependencies" => {}
            }
        }
    }
}

这是我的子程序:

sub get_starting_point {
    my $string = shift;
    my $config = shift;
    foreach my $key (keys %$config) {
        if($key ne $string) {
            # if current key is not what user asked for, recurse into next level of hierarchy
            if (exists $$config{$key}{dependencies}) {
                &get_starting_point($$config{$key}{dependencies});
            }
        } else {
            # we found the key, return the hash under this hierarchy
            my $tempHash = {$key => $$config{$key}};
            print ref($tempHash); # correctly prints HASH
            print Dumper($tempHash); # correctly prints out the sub-hash
            return $tempHash; # I am expecting this return value to be a hash-ref
        }
    }
}

如您所见,这是一个递归函数,它不断深入哈希,直到找到与参数匹配的键并返回该键下的完整子哈希。

这就是我调用这个子例程的方式。

my $subHash = get_starting_point("sub_block2",$HASH);
print ref($subHash); # is not a ref
print Dumper($subHash); # prints nothing

我究竟做错了什么!?!?

编辑:用我的确切问题更新了问题。似乎是我之前使用的一个简单示例,按预期工作。

4

2 回答 2

2

您正在返回 foreach 评估的值(由于是 sub 的最后一条语句)。这不是参考也就不足为奇了。

&get_starting_point($$config{$key}{dependencies});

应该

my $rv = get_starting_point($config->{$key}{dependencies});
return $rv if $rv;

return undef;在最后添加而不是依靠 foreach 返回一些错误的东西。

sub get_starting_point {
    my $string = shift;
    my $config = shift;
    for my $key (keys %$config) {
        if ($key eq $string) {
            return { $key => $config->{$key} };
        }

        if ($config->{$key}{dependencies}) {
           my $rv = get_starting_point($config->{$key}{dependencies});
           return $rv if $rv;
        }
    }

    return undef;
}

笔记:

  • 请不要使用&. 你甚至知道那是做什么的吗?
  • 大多数人发现$config->{$key}$$config{$key}.
于 2014-11-21T04:20:49.857 回答
0

哎哟。我假设递归函数中的“return”语句立即脱离递归并返回值。它没有。因此,当递归尽可能深入并开始返回时,就没有什么可以返回了。

我通过在子例程之外设置一个全局来解决这个问题,在子例程内,我只是将这个全局设置为子哈希。

这符合我的目的!

于 2014-11-21T04:21:08.273 回答