Arrays 在Perl中,如何将长度未知的文件读入多个散列以存储在数组中供以后使用?

Arrays 在Perl中,如何将长度未知的文件读入多个散列以存储在数组中供以后使用?,arrays,perl,hash,Arrays,Perl,Hash,我有一个配置文件,看起来有点像这样: add 1 2 concatenate foo bar blat my %temphash = (name=>'add', args=>[1,2]); push (@array, \%temphash); 我要做的是将其转换为散列,如%hash=(name=>“add”,args=>[1,2])等,并将散列引用推送到单个数组中。在文件中循环并创建每个散列似乎足够简单,除非在命名这些散列以将它们的引

我有一个配置文件,看起来有点像这样:

add
    1
    2
concatenate
    foo
    bar
    blat
my %temphash = (name=>'add', args=>[1,2]);  

push (@array, \%temphash);
我要做的是将其转换为散列,如
%hash=(name=>“add”,args=>[1,2])
等,并将散列引用推送到单个数组中。在文件中循环并创建每个散列似乎足够简单,除非在命名这些散列以将它们的引用推送到数组中时我遇到了困难。配置文件将一直更改,并且要存储不同数量的名称/参数组合。有没有一种方法可以遍历散列名,这样我就可以一次一个地将它们放入数组中

目前看来是这样的:

add
    1
    2
concatenate
    foo
    bar
    blat
my %temphash = (name=>'add', args=>[1,2]);  

push (@array, \%temphash);
我是否可以将该
%temphash
转换为动态生成的内容,并在转到下一个之前将其推送

编辑:上下文

计划是使用这些“名称”键来调用子例程。所以像这样的东西可以起作用:

my %subhash = (add=>\&addNumbers, concatenate=>\&concat);

除了我需要调用的子程序列表在配置文件中之外,我不知道它们是什么,直到我开始阅读它。即使我在配置文件中包含了子例程的名称,我如何遍历它们并将它们作为元素添加到该散列中?

如果我正确理解了您的要求,那么您可以编写:

push @array, { name=>'add', args=>[1,2] };
其中,
{…}
是对匿名哈希的引用

也就是说,我有点惊讶于您需要一个哈希数组,而每个哈希只有一个
名称
args
。为什么不使用从名称到参数的单个哈希映射

%array = ( add => [ 1, 2 ], concatenate => [ 'foo', 'bar', 'baz' ] );

如果我正确理解了你的要求,那么你可以写:

push @array, { name=>'add', args=>[1,2] };
其中,
{…}
是对匿名哈希的引用

也就是说,我有点惊讶于您需要一个哈希数组,而每个哈希只有一个
名称
args
。为什么不使用从名称到参数的单个哈希映射

%array = ( add => [ 1, 2 ], concatenate => [ 'foo', 'bar', 'baz' ] );

好的,您可以简单地使用花括号创建匿名哈希:

push @array, { name => 'add', args => [1,2] };
您可以通过使用
my
声明的词法范围来创建相同的效果。例如:

my @array;
while ( ... ) {
    ...
    my %hash = ( ... );
    push @array, \%hash;
}

好的,您可以简单地使用花括号创建匿名哈希:

push @array, { name => 'add', args => [1,2] };
您可以通过使用
my
声明的词法范围来创建相同的效果。例如:

my @array;
while ( ... ) {
    ...
    my %hash = ( ... );
    push @array, \%hash;
}

像这样的东西可以满足你的需要

use strict;
use warnings;

open my $fh, '<', 'data_file' or die $!;

my $item;
my @data;

while (<$fh>) {
  chomp;
  next unless /^(\s*)(.+?)\s*$/;
  if ($1) {
    push @{ $item->{args} }, $2;
  }
  else {
    push @data, $item if $item;
    $item = { name => $2, args => [] };
  }
}
push @data, $item if $item;

use Data::Dump;
dd \@data;

像这样的东西可以满足你的需要

use strict;
use warnings;

open my $fh, '<', 'data_file' or die $!;

my $item;
my @data;

while (<$fh>) {
  chomp;
  next unless /^(\s*)(.+?)\s*$/;
  if ($1) {
    push @{ $item->{args} }, $2;
  }
  else {
    push @data, $item if $item;
    $item = { name => $2, args => [] };
  }
}
push @data, $item if $item;

use Data::Dump;
dd \@data;

我有点困惑。也许您正在寻找
$temphash{$key}=>[1,2]
where
$key='add'
我有点困惑。也许您正在寻找
$temphash{$key}=>[1,2]
where
$key='add'
对动态文件使用单个哈希可能会覆盖出现在不同位置的相同键。对动态文件使用单个哈希可能会覆盖出现在不同位置的相同键。新手问题:如果%hash的作用域仅限于该循环,我仍然可以遍历该数组中的元素吗在别处我从来没有做过匿名散列。听起来有颠覆性。数据将保存在数组中,引用仍将指向内存中的同一地址。但是,名称空间引用(例如,
%hash
)将被销毁。匿名散列/数组是解决这些“一次性变量”情况的非常好的方法。好的,还有一个问题需要解决。我使用这个数组来执行类似的操作:
foreach(@array){print“Yo\n”;}
但它最终会为存储的每个哈希值(名称和参数)运行该块一次,而不是为每个哈希运行一次。这与散列是匿名的有关吗,还是我缺少了一些更基本的内容?新手问题:如果%hash只作用于该循环,我还能在其他地方迭代该数组中的元素吗?我从来没有做过匿名散列。听起来有颠覆性。数据将保存在数组中,引用仍将指向内存中的同一地址。但是,名称空间引用(例如,
%hash
)将被销毁。匿名散列/数组是解决这些“一次性变量”情况的非常好的方法。好的,还有一个问题需要解决。我使用这个数组来执行类似的操作:
foreach(@array){print“Yo\n”;}
但它最终会为存储的每个哈希值(名称和参数)运行该块一次,而不是为每个哈希运行一次。这和散列的匿名性有什么关系吗?还是我缺少了一些更基本的东西?