2

这是我的问题:

我有一个类似数据结构的文件系统:

%fs = (
    "home" => {
        "test.file"  => { 
            type => "file",
            owner => 1000, 
            content => "Hello World!",
        },
    },
    "etc"  => { 
        "passwd"  => { 
            type => "file",
            owner => 0, 
            content => "testuser:testusershash",
            },
        "conf"  => { 
            "test.file"  => { 
                type => "file",
                owner => 1000, 
                content => "Hello World!",
            },
        },
    },
);

现在,要获取/etc/conf/test.file我需要的内容$fs{"etc"}{"conf"}{"test.file"}{"content"},但我的输入是一个数组,看起来像这样:("etc","conf","test.file")

所以,因为输入的长度不同,我不知道如何访问散列的值。有任何想法吗?

4

6 回答 6

5

您可以使用循环。在每一步中,您都会更深入地了解结构。

my @path = qw/etc conf test.file/;
my %result = %fs;
while (@path) {
    %result = %{ $result{shift @path} };
}
print $result{content};

您还可以使用Data::Diver

于 2012-07-31T11:17:35.093 回答
1
my @a = ("etc","conf","test.file");

my $h = \%fs;
while (my $v = shift @a) {
  $h = $h->{$v};
}
print $h->{type};
于 2012-07-31T11:21:03.093 回答
1

与其他人给出的逻辑相同,但使用foreach

@keys = qw(etc conf test.file content);
$r = \%fs ;
$r = $r->{$_} foreach (@keys);
print $r;
于 2012-07-31T12:36:42.867 回答
0
$pname = '/etc/conf/test.file';
@names = split '/', $pname;
$fh = \%fs;
for (@names) {
    $fh = $fh->{"$_"} if $_;
}
print $fh->{'content'};
于 2012-07-31T12:46:36.363 回答
0

Path::Class 接受一个数组。它还为您提供了一个带有辅助方法的对象并处理跨平台斜线问题。

https://metacpan.org/module/Path::Class

于 2012-07-31T15:05:24.297 回答
-1

您可以只构建哈希元素表达式并调用eval. 如果将其包装在子例程中,则更整洁

my @path = qw/ etc conf test.file /;

print hash_at(\%fs, \@path)->{content}, "\n";

sub hash_at {
  my ($hash, $path) = @_;
  $path = sprintf q($hash->{'%s'}), join q('}{'), @$path;
  return eval $path;
}
于 2012-07-31T11:38:44.670 回答