Perl - 哈希的哈希 - 是使用“eval”访问可变长度键序列的唯一选项吗?{k[0]}=>{k[1]}=>

pkr*_*171 1 perl hash-of-hashes

我将保持我的问题的高度,因为这就是我,这就是我的风格,这就是我需要回答的问题。

我有一个多级哈希可以使用(哈希的哈希)。我还有一些算法可以为我提供 @key 中的一系列键(用于查找各种值)。

我获取个人价值观的技巧是:

只需构建一个如下所示的表达式

 $h-> {$key[0] }=> {$key[1]} => ... e.t.c.
Run Code Online (Sandbox Code Playgroud)

然后“评估”该表达式。

是否有更好的技术来处理可变按键序列而不需要 eval?

(哈希是目录结构的镜像。值是单个文件,我的程序需要读取这些文件的内容。)

我尝试过,它适用于 eval 选项。

ike*_*ami 7

Data::Diver让这一切变得简单。

use Data::Diver qw( DiveVal Dive );

my $h;

DiveVal( $h, map \$_, @keys ) = 123;

say Dive( $h, map \$_, @keys );   # 123
Run Code Online (Sandbox Code Playgroud)

您可以使用${ DiveRef( ... ) }代替DiveVal.


您还可以使用以下内容:

sub dive {
   my $x = shift;
   $x &&= $x->{ $_ } for @_;
   $x
}

sub dive_ref {
   my $p = \shift;
   $p = \( ($$p)->{ $_ } ) for @_;
   $p
}

sub dive_val :lvalue {
   my $p = \shift;
   $p = \( ($$p)->{ $_ } ) for @_;
   $$p
}

my $h;

dive_val( $h, @keys ) = 123;

say dive( $h, @keys );   # 123
Run Code Online (Sandbox Code Playgroud)

您可以使用${ dive_ref( ... ) }代替dive_val.


dive_ref可以适用于从文件树创建数据结构。

sub load_data {
   my $p       = \shift;
   my $dir_qfn =  shift;

   my ( @d_fns, @f_fns );

   {
      opendir( my $dh, $dir_qfn )
         or die( "Can't open `$dir_qfn`: $!\n" );

      while ( defined( my $fn = readdir( $dh ) ) ) {
         next if $fn =~ /^\./;

         my $qfn = "$dir_qfn/$fn";
         stat( $qfn )
            or die( "Can't stat `$qfn`: $!\n" );

         push @{ -d _ ? \@d_fns : \@f_fns }, $fn;
      }
 
      closedir( $dh )
         or die( "Error reading `$dir_qfn`: $!\n" );
   }

   ($$p)->{ ".files" } = \@f_fns;  # Or whatever.

   load_data( ($$p)->{ $_ }, "$dir_qfn/$_" ) for @d_fns;
}

load_data( my $data, "." );
Run Code Online (Sandbox Code Playgroud)