in reply to Data::Dumper is returning empty

As you may have guessed, the reason Data::Dumper is returning empty is because you are feeding it an empty variable. The reason %nic is empty is because you are having scoping issues. You declare a hash %nic on line 5 of the posted code and that is what gets fed into your print statement on line 45. However, on lines 10 and 28 you have the statement my %nic;. This creates a new variable, scoped to each iteration of your for loops, that overrides the previous entry in the symbol table so long as it is in scope - see Private Variables via my(). The solution to your problem should be as simple as deleting lines 10 and 28.

Update: See ikegami's response below, regarding creating a array of hashes to export your results. It is a scoping issue, but not quite what I initially thought.

Replies are listed 'Best First'.
Re^2: Data::Dumper is returning empty
by ikegami (Patriarch) on Jan 19, 2010 at 18:00 UTC

    Good explanation, but the conclusion is backwards. Line 10 and 28 are correct; it's line 5 that's wrong. There are multiple nics, so there should be multiple hashes. The real problem is that the function pretends there's only one. It should be returning a list of nics (list of hashes).

    sub networkInfo { my @nics; my $platform = getPlatform(); if ($platform =~ /RedHat/) { my $ifconfig = qx|/sbin/ifconfig| or die("Can't get info from Linux ifconfig: $!\n"); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = /^(eth\d)\s/ or next; if (/\binet addr:([\d.]+)\s.+?:([\d.]+)\s.+?:([\d.]+)/) { $nic{ip} = $1; $nic{bcast} = $2; $nic{mask} = $3; } if (/^\s+ inet6 addr:\s*(\S+)/m) { $nic{ip6} = $1; } push @nics, \%nic; } } elsif ($platform =~ /SunOS/) { my $ifconfig = qx|/sbin/ifconfig -a| or die("Can't get info from Solaris ifconfig: $!\n"); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = /^(fjgi\d)\s/ or next; if (/\binet addr:([\d.]+)\s.+?:([\d.]+)\s.+?:([\d.]+)/) { $nic{ip} = $1; $nic{bcast} = $2; $nic{mask} = $3; } if (/^\s+ inet6 addr:\s*(\S+)/m) { $nic{ip6} = $1; } push @nics, \%nic; } } return @nics; } for my $nic (networkInfo()) { print(join( "\t", map $_//'[undef]', @{$nic}{qw( device ip ipv6 bcast mask )} ), "\n"); }

    Update: Cleaned up opening paragraph.
    Update: Second push discovered ability to turn invisible. Added anti-invisibility field to post so it's visible again.

      I am getting an error when I try to run this code. It says

      Search pattern not terminated at ./sec-test.pl line 166 (#1) (F) The lexer couldn't find the final delimiter of a // or m{} construct. Remember that bracketing delimiters count nesting level. Missing the leading $ from a variable $m may cause this error. Note that since Perl 5.9.0 a // can also be the defined-or construct, not just the empty search pattern. Therefore code written in Perl 5.9.0 or later that uses the // as the defined-or can be misparsed by pre-5.9.0 Perls as a non-terminated search pattern. Uncaught exception from user code: Search pattern not terminated at ./sec-test.pl line 166. at ./sec-test.pl line 166

      line 166 is the map $_//'[undef]', line

      Also how would I return to main so I could run the following code section, or code similar to what I have below?

      my %nicdata = networkInfo($platform); for (@nicdata) { print "Device: $nic{device} has the IP Address of $nic{ip}\n\tMask +: $nic{mask}\n\tBroadcast: $nic{bcast}\n"; print "Device: $nic{device} also has IPv6 address of $nic{ip6}\n"; }
        Sorry, I used a 5.10 construct. Change
        map $_ // '[undef]'
        to
        map defined($_) ? $_ : '[undef]'

        Update:

        Concerning the code you posted, you introduced numerous errors:

        • You're assigning a list of nicdata to a hash.
        • Your hash is named nicdata, but it does contains the data about multiple nics.
        • You use @nicdata without ever placing any information in it.
        • Your array is named nicdata, but it's suppose to contain the data about multiple nics.
        • You use %nic without ever placing any information in ti.
        • You pass $platform as an argument as though it can change.
        for my $nic (networkInfo()) { print "Device: $nic->{device} has IP Address $nic->{ip}\n" . "\tMask: $nic->{mask}\n" . "\tBroadcast: $nic->{bcast}\n"; print "Device: $nic->{device} also IPv6 address $nic->{ip6}\n" if defined($nic->{device}); }