谁能告诉我为什么我的参考不会被退回?

时间:2011-04-07 17:31:56

标签: perl

我正在为Netscreen防火墙配置文件编写一个解析器,以创建一些与我使用PIX :: Walker的脚本相同的脚本。我遇到了一个问题,我在parseconfig子中创建的引用在转储1中看起来很好,但在转储2中是空的。我现在正在研究一种更清洁的方法,但我想知道是否有人能告诉我为什么转储2显示引用为空。

#!/usr/bin/perl

use strict;
use Getopt::Std;
use Data::Dumper;

my $usage = "Usage: isg-ppsrpt.pl -d config directory
-d is required
use portproto-rpt.pl -h to get this help\n\n";

my @firewalls = ("foo","bar","baz");

my %opts;
my %configs;

getopts('hd:', \%opts);

if ($opts{h}) { die $usage };

# Parser definition
my %parse;

$parse{service} = sub {
 my $ref = shift;
 my @elements = split(/\s+/, shift);
 @elements[2]  =~ /\"(\S+)\"/;
 my $name = $1;
 my $out;
 if ($elements[4] =~ /tcp|udp/) {
  $out->{proto} = $elements[4];
  $out->{port} = $elements[-1];
 }
 if ($out) {push @{$ref->{service}{$name}}, $out};
};


foreach (@firewalls) {
 my $fw = sprintf "%s\\%s.config",$opts{d},$_;
 if (-e $fw) {
  $configs{$_} = parseconfig($fw);
 } else {
  die "Cannot find config file for $_ in \n";
 }
}

sub parseconfig {
  my $configref;
  my $configfile = shift;
  open (CONFIG,"$configfile");
  foreach my $line (<CONFIG>) {
   chomp $line;
   my $type = (split(/\s+/,$line))[1];
   if ($parse{$type}) {
    $parse{$type}($configref,$line);
   }
   print Dumper(%$configref); # Dump 1
  }
  close(CONFIG);
  print Dumper(%$configref); # Dump 2
  return($configref);
}

2 个答案:

答案 0 :(得分:2)

sub parseconfig {
    my $configref;
    ....
    if ($parse{$type}) {
        $parse{$type}($configref,$line);

我不知道这解释了你的问题,但看起来你依靠被调用的函数来填充$ configref。这仅在直接使用$_[0](传递的参数$configref的别名)时才有效;如果它将它分配给词汇并使用它,$configref本身将保持未定义。在parseconfig中将$configref初始化为{}会修复此问题。

答案 1 :(得分:1)

通过自动更新,您可以为$ref分配哈希引用。但是,该参考永远不会在调用者中分配给$configref

更改$ref不会更改$configref,因此$configref仍未定义。由于$_[0]别名为$configref,因此更改$_[0]会更改$configref

您必须找到在$ref$configref中放置相同引用的方法。

解决方案1:

$parse{service} = sub {
    my $ref = $_[0] ||= {};
    ...
};

my $configref;
...
$parse{$type}($configref, $line);

解决方案2:

$parse{service} = sub {
    my $ref = $_[0];
    ...
};

my %config;
...
$parse{$type}(\%config, $line);

解决方案3:

$parse{service} = sub {
    my %config;
    ...
    return %config;
};

my %config;
...
%config = ( %config, $parse{$type}($line) );