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

hello monks

I' m in fix with the below code (that is a simplified version of my code, only to show the problem, thaks to wfsp).
use warnings; use strict; use Data::Dumper; my @temp; $temp[12] = q{one two three }; my %hash = ( alias => { map {$_ => risolve( $_ );} split / /,$temp[12] }, ); sub risolve{ my $host = shift; open DNS, "ping -l o -n 1 $host >nil|"||die; while (<DNS>) {1} ### COMMENT THIS LINE AND IT WORKS close DNS; return q{four five six}; } print Dumper \%hash;
if run as is it prints:
$VAR1 = { 'alias' => { '' => 'four five six' } };
and it warns
Use of uninitialized value in anonymous hash ({}) at wsfp-scratchpad2. +pl line 11. Use of uninitialized value in anonymous hash ({}) at wsfp-scratchpad2. +pl line 11. Use of uninitialized value in anonymous hash ({}) at wsfp-scratchpad2. +pl line 11.
but if you comment out the line while (<DNS>) {1} it prints as expected:
$VAR1 = { 'alias' => { 'three' => 'four five six', 'one' => 'four five six', 'two' => 'four five six' } };
what is happening?
thanks in advance
Lor*

Replies are listed 'Best First'.
Re: problem with $ARG
by Random_Walk (Prior) on Feb 05, 2009 at 10:56 UTC

    briefly, risolve is clobbering your $_ which is the default place to which you read the records from the DNS handle. $_ is a global variable so this self same $_ is then used as the key for your hash.

    while (my $discard = <DNS>) {1}; # this would fix it

    If risolve is intended to resolve the IP address of the hosts you can do this with pure Perl using gethostbyname. This will return a record that you will need to process to get human readable IP address, the linked docco explains how to do this.

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
      The way to use gethostbyname can be illustrated thusly
      perl -MSocket -M5.010 -e 'say inet_ntoa((gethostbyname("name"))[4]);'

        -M5.010 -e
        can be written as
        -E

        (gethostbyname($ARGV[0]))[4])
        is clearer as
        scalar(gethostbyname($ARGV[0]))
        or just
        gethostbyname($ARGV[0])
        if you check if gethostbyname succeeded.

        perl -MSocket -E'say inet_ntoa gethostbyname(shift)||die "Not found\n"' example.com

Re: problem with $ARG
by linuxer (Curate) on Feb 05, 2009 at 10:59 UTC
    open DNS, "ping -l o -n 1 $host >nil|"||die;

    Beware of the precedence of the operators.

    Better (iirc):

    open( DNS, "ping -l o -n 1 $host >nil|" ) || die $!; # or open DNS, "ping -l o -n 1 $host >nil|" or die $!;

    Update:
    And I wonder, why you redirect STDOUT of the ping to "nil" and want to parse the STDOUT via Pipe into your Perl program?

    Please redirect the output to the file and parse that file afterwards, or redirect the output via Pipe to the Perl program and parse it directly.

    open my $pipe, '-|', "ping -l o -n 1 $host" or die $!;