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

ループを使用できます。各ステップで、構造を 1 レベル深く進めます。

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/パス::クラス

于 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 に答える