Perl 解引用多级散列:一个实际示例

Perl 解引用多级散列:一个实际示例,perl,hash,dereference,multi-level,Perl,Hash,Dereference,Multi Level,我有一个数据,我把它输入到这个多级散列中: $newcomm_stat_hash{$stat_message_class}{$stat_process} = $stat_host; 我可以用 关键值结构: foreach my $stat_message_class (keys %newcomm_stat_hash) { my $stat_message_type = $stat_message_class; foreach my $stat_process (keys %{$

我有一个数据,我把它输入到这个多级散列中:

$newcomm_stat_hash{$stat_message_class}{$stat_process} = $stat_host;
我可以用 关键值结构:

foreach my $stat_message_class (keys %newcomm_stat_hash) {

   my $stat_message_type = $stat_message_class;

   foreach my $stat_process (keys %{$newcomm_stat_hash{$stat_message_class}} ) {

      print $stat_host;
   }
}
但是,当我按照相同的格式打印出
$stat\u主机值
(请参见下面的代码)时,我会收到以下错误消息:

在多级_散列第24行使用“strict refs”时,不能将字符串(“dc109”)用作散列引用

对于键或值函数,我得到了相同的消息

#!/usr/bin/perl
use warnings; 
use strict;

my %newcomm_stat_hash; 
my $control_server = "dc100";
my $control_stat_message = "OCCD2o";

$newcomm_stat_hash{'OCCD2o'} =  { 'filesrvr' => 'dc100',
                                  'dhcpsrv'  => 'dc100',
                                  'dnssrv'   => 'dc109',
                                  'mailpfd'  => 'dc100',
                                };

$newcomm_stat_hash{'PIDmon2'} = { 'pingstat' => 'fg100',
                                  'udpmon'   => 'fg100',
                                  'ftp'      => 'dc100',
                                  'casper'   => 'dc440',
                                };

foreach my $stat_message_class ( keys %newcomm_stat_hash ) {

 my $stat_message_type = $stat_message_class;

 foreach my $stat_process ( keys %{$newcomm_stat_hash{$stat_message_class}} ) {

         foreach my $stat_host (keys %{$newcomm_stat_hash{$stat_message_class}{$stat_process}} ) {

             print $stat_host;
         } 
     }
}
在将多级散列解引用到
$stat\u host
之后,我想在末尾插入以下内容:

use TERM::ANSIColor;

if ($stat_host ne $control_server) {

    print "$stat_host, $stat_process , $stat_message_class";   
}   

elsif (  ($stat_host ne $control_server)
      && ($stat_message_class eq $control_stat_message)
      ) {   

    print color 'red';   
    print "$stat_host, $stat_process , $stat_message_class";
    print color 'reset';   
}

如果我正确理解您的代码,您会说
OCCD2o
是一个“消息类”;
filesrvr
是一个“进程”;
dc100
是“主机”。如果是这种情况,则不需要最内层的“foreach”循环,因为您已经处于hashref散列的“主机”级别。在这个层次上你不能再深入了

因此,如果将表达式
%{$newcommm_stat_hash{$stat_message_class}{$stat_process}}
重写为:

$tmp=$newcommm\u stat\u hash{$stat\u message\u class}{$stat\u process}
$hash=%{$tmp}
然后将
$tmp
计算为字符串标量
dc109
,该标量不能作为散列解引用,因此显示错误消息

我认为这是正确的循环结构:

foreach my $stat_message_class (keys %newcomm_stat_hash) {

   my $stat_message_type = $stat_message_class;

   foreach my $stat_process (keys %{$newcomm_stat_hash{$stat_message_class}} ) {

      print $stat_host;
   }
}
foreach my$stat\u message\u类(键%newcommm\u stat\u散列){
my$stat_hash=$newcommm_stat_hash{$stat_message_class};
我的$stat\u message\u type=$stat\u message\u类;
foreach my$stat_进程(键%{$stat_hash}){
my$stat_host=$stat_hash->{$stat_process};
打印$stat\u消息\u类“/”、$stat\u进程“/”、$stat\u主机“\n”;
}
}

看起来这里的目标是以红色打印对应于
$control\u server
$control\u stat\u message
的哈希条目

如果是这样,条件语句将不会执行您希望它执行的操作,因为
elsif
子句将永远不会执行