Разыменование многоуровневого хэша: практический пример - PullRequest
0 голосов
/ 23 июля 2011

У меня есть данные, которые я закачиваю в этот многоуровневый хэш:

$newcomm_stat_hash{$stat_message_class}{$stat_process} = $stat_host;

Я могу распечатать $stat_message_class и $stat_process со структурой ключей-значений:

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_host values по тому же формату (см. Код ниже), я получаю следующее сообщение об ошибке:

Невозможно использовать строку ("dc109")в качестве ссылки HASH, в то время как в строке multilevel_hash используются «строгие ссылки».

Я получаю то же сообщение для функции ключей или значений.

#!/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_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';   
}

Ответы [ 2 ]

1 голос
/ 23 июля 2011

Если я правильно понимаю ваш код, ваше высказывание о том, что OCCD2o - это "класс сообщений", filesrvr - это "процесс", а dc100 - это "хост". Если это так, то внутренний цикл «foreach» не нужен, так как вы уже находитесь на уровне «хоста» ваших hash-of-hashrefs. Вы не можете идти глубже на этом уровне.

Так что если вы переписываете выражение %{$newcomm_stat_hash{$stat_message_class} {$stat_process}} как:

$tmp = $newcomm_stat_hash{$stat_message_class}{$stat_process}
$hash = %{$tmp}

затем $tmp оценивается как строковый скаляр dc109, который не может быть разыменован как хеш, поэтому отображается сообщение об ошибке.

Я бы сказал, что это правильная структура цикла:

foreach my $stat_message_class(keys %newcomm_stat_hash){
    my $stat_hash = $newcomm_stat_hash{$stat_message_class};
    my $stat_message_type = $stat_message_class;
    foreach my $stat_process (keys %{$stat_hash}){
        my $stat_host = $stat_hash->{$stat_process};

        print $stat_message_class, " / ", $stat_process, " / ", $stat_host, "\n";
    }
}
0 голосов
/ 23 июля 2011

Похоже, цель здесь состоит в том, чтобы напечатать в записи хеша, которые соответствуют $control_server и $control_stat_message красным цветом.

Если это так, условное выражение не будет выполнять то, что вам нужно, потому что предложение elsif не выполнит никогда .

#!/usr/bin/perl
use warnings; 
use strict;
use Term::ANSIColor;

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 $message_class = $newcomm_stat_hash{$stat_message_class};

    foreach my $stat_process ( keys %{ $message_class } ) {

        my $host = $message_class->{$stat_process};

        my $info = join(', ', $stat_message_class, $stat_process, $host) . "\n";

        if (   $stat_message_class eq $control_stat_message
           &&  $host eq $control_server
           )
        {

            print colored ( $info, 'red' );  # Prints $info in red
        }

        else {

            print $info;                     # Prints $info normally
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...