取消引用多级哈希:一个实际示例

发布于 2024-11-25 18:46:14 字数 2152 浏览 5 评论 0原文

我有一个数据被注入到这个多级哈希中:

$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 值(参见下面的代码)时,我收到此错误消息:

在 multilevel_hash 第 24 行使用“严格引用”时,无法使用字符串(“dc109”)作为 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';   
}

I have a data that I pump into this multi-level hash:

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

I can print out the $stat_message_class, and the $stat_process with the
keys-values structure:

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;
   }
}

But when I follow the same format to print out $stat_host values (see code below), I get this error message:

Can't use string ("dc109") as a HASH ref while "strict refs" in use at multilevel_hash line 24.

I get the same message for the keys or values function.

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

After dereferencing the multilevel hash to $stat_host I want to plug this in at the end:

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';   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铃予 2024-12-02 18:46:14

如果我正确理解您的代码,您所说的 OCCD2o 是一个“消息类”,filesrvr 是一个“进程”,dc100 是“主机” ”。如果是这种情况,则不需要最里面的“foreach”循环,因为您已经处于哈希引用的“主机”级别。你无法在那个层面上走得更深。

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

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

$tmp 将被计算为字符串标量 dc109< /code> 不能作为散列取消引用,因此会显示错误消息。

我想说这是正确的循环结构:

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";
    }
}

If I understand your code correctly your saying that OCCD2o is a "message class", filesrvr is a "process" and dc100 is the "host". If thats the case then the innermost "foreach" loop is not necessary, since you are already at the "host"-level of your hash-of-hashrefs. You can't go deeper at that level.

So if you rewrite the expression %{$newcomm_stat_hash{$stat_message_class} {$stat_process}} as:

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

then $tmp gets evaluated to a string-scalar dc109 which cant be dereferenced as hash thus the error-message is shown.

I would say this is the correct loop-structure:

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";
    }
}
不如归去 2024-12-02 18:46:14

看起来这里的目标是打印对应于红色的 $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
        }
    }
}

Looks like the objective here is to print in the hash entry that correspond to $control_server and $control_stat_message in red.

If so, the conditional will not do what you want it to, because the elsif clause will never execute.

#!/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
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文