Ravendark has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I have an array of 600 elements (indices of interfaces) and 10 ini-style files. each ini-style file has the form:
[2287] slot = 20 port = 1
each one of them having 60 sections (which represent 60 ports of a machine.) and I have a piece of code that takes an ifindex and stores the values of slot & port into two separate arrays.
sub translate_ifindex() { my $ports_ini_dir = "/home/portal/bin/conf/snmp_set"; my $slot; my $port; for ($t = 0; $t < @ifindex; $t++) { #print "IFINDEX: $ifindex[$t]\n"; if ($ifindex[$t] >= 204 && $ifindex[$t] <= 381) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot02.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 22 && $ifindex[$t] <= 199) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot04.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 513 && $ifindex[$t] <= 690) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot06.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 823 && $ifindex[$t] <= 1000) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot08.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 1067 && $ifindex[$t] <= 1244) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot10.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 1311 && $ifindex[$t] <= 1488) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot12.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 1555 && $ifindex[$t] <= 1732) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot14.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 1799 && $ifindex[$t] <= 1976) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot16.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 2043 && $ifindex[$t] <= 2220) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot18.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } if ($ifindex[$t] >= 2287 && $ifindex[$t] <= 2464) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/s +nmp_ports_slot20.txt" ); $slot = $cfg->val("$ifindex[$t]", "slot"); $port = $cfg->val("$ifindex[$t]", "port"); push @msan_slot, $slot; push @msan_port, $port; } } }
every time I run it I get this: Can't call method "val" on an undefined value at /home/portal/bin/snmp_set.pl line 142. and line 142 is: $slot = $cfg->val("$ifindex[$t]", "slot"); in the last if statement. If I comment out this section, the program runs without problem. Thanks in advance.

Replies are listed 'Best First'.
Re: Undefined value
by wfsp (Abbot) on Jun 19, 2009 at 12:21 UTC
    First I think I'd check that
    my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/snmp_ports_sl +ot20.txt" );
    succeeded. Perhaps something like
    my $cfg_file = q{$ports_ini_dir/snmp_ports_slot20.txt}; my $cfg = Config::IniFiles->new( -file => $cfg_file) or die qq{cant open *$cfg_file*: $!};
Re: Undefined value
by wfsp (Abbot) on Jun 19, 2009 at 13:13 UTC
    This is similar to Anonymous Monk's suggestion but builds a lookup table. Tables can often simplify your logic and avoid a string of if blocks.
    #! /usr/bin/perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Indent = 2; my @ranges = ( # low high conf_file [ 204, 381, 2], [ 22, 199, 4], [ 513, 690, 6], [ 823, 1000, 8], [1067, 1244, 10], [1311, 1488, 12], [1555, 1732, 14], [1799, 1976, 16], [2043, 2220, 18], [2287, 2464, 20], ); my %lookup; for my $range (@ranges){ my ($low, $high, $slot) = @{$range}; for my $index ($low..$high){ $lookup{$index} = $slot; } } #print Dumper \%lookup; #exit; my @ifindex = (204, 22, 513); my ($msan_slot, $msan_port) = translate_ifindex(@ifindex); sub translate_ifindex { my @ifindex = @_; my $ports_ini_dir = "/home/portal/bin/conf/snmp_set"; my (@msan_slot, @msan_port); for my $t (0..$#ifindex) { if (exists $lookup{$t}){ my $cnf_file = sprintf(q{%s/snmp_ports_slot%02d.txt}, $ports_ini +_dir, $lookup{$t}); my $cfg = Config::IniFiles->new( -file => $cnf_file) or die q{cant open *$cnf_file*}; my $slot = $cfg->val($ifindex[$t], "slot"); my $port = $cfg->val($ifindex[$t], "port"); push @msan_slot, $slot; push @msan_port, $port; } } return \@msan_slot, \@msan_port; }
    Untested due to not having the config files.

    updated: corrected table syntax and sprintf format string

Re: Undefined value
by Anonymous Monk on Jun 19, 2009 at 12:21 UTC
    Why assume Config::IniFiles->new success? Doc say "undef" if the configuration file has an error, in which case check the global @Config::IniFiles::errors array for reasons why
      sub translate_ifindex() { my $ports_ini_dir = "/home/portal/bin/conf/snmp_set"; my (@range_files) = ( [ 204, 381, "snmp_ports_slot02.txt", ] [ 22, 199, "snmp_ports_slot04.txt", ] [ 513, 690, "snmp_ports_slot06.txt", ] [ 823, 1000, "snmp_ports_slot08.txt", ] [ 1067, 1244, "snmp_ports_slot10.txt", ] [ 1311, 1488, "snmp_ports_slot12.txt", ] [ 1555, 1732, "snmp_ports_slot14.txt", ] [ 1799, 1976, "snmp_ports_slot16.txt", ] [ 2043, 2220, "snmp_ports_slot18.txt", ] [ 2287, 2464, "snmp_ports_slot20.txt", ] ); for ( my $t = 0 ; $t < @ifindex ; $t++ ) { for my $range_file (@range_files) { if ( $ifindex[$t] >= $$range_file[0] && $ifindex[$t] <= $$range_file[1] ) { my $cfg = new Config::IniFiles( -file => "$ports_ini_dir/$$range_file[2]" ); if ($cfg) { push @msan_slot, $cfg->val( $ifindex[$t], "slot"); push @msan_port, $cfg->val( $ifindex[$t], "port"); } else { warn "Ooops($$range_file[2]): @Config::IniFiles::e +rrors"; } } } } }
      yes it dies... but I cannot figure out why it cannot open the specific file... It was working earlier...
        Error message tells you why.