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

Why am I getting the following output when I use warnings?
ive tried it a couple different ways but am always getting
similar results.

There are 3 hosts down
There are 1 hosts alive

The following hosts are alive:
pcbackup
Use of uninitialized value in concatenation (.) or string
at ./mship.pl line 33.


The following hosts are down:
host1
host2
host3
Use of uninitialized value in concatenation (.) or string
at ./mship.pl line 38.


#!/usr/bin/perl use strict; use warnings; use Net::Ping; my @hosts = qw/host1 host2 host3 pcbackup/; # my $net="myhost\.com"; # unused for now my $proto="icmp"; my $p = Net::Ping->new($proto); my @uphosts=(); my @downhosts=(); foreach my $host(@hosts) { if ($p->ping($host)) { push (@uphosts, $host); } else { push (@downhosts, $host); } } $p->close(); $#downhosts++; $#uphosts++; print "There are $#downhosts hosts down\n"; print "There are $#uphosts hosts alive\n\n"; print "The following hosts are alive: \n"; foreach my $item (@uphosts) { print "$item\n"; } print "\nThe following hosts are down: \n"; foreach my $item (@downhosts) { print "$item\n"; }

Thanks in advance
Ted

Replies are listed 'Best First'.
Re: how is this uninitialized?
by dragonchild (Archbishop) on Dec 28, 2004 at 15:56 UTC
    $#downhosts++; $#uphosts++;
    You're altering the array size - increasing it by one. So, there's now an undefined value at the end of both your arrays.

    Better would be:

    print "There are ", scalar(@downhosts), " hosts down\n"; print "There are ", scalar(@uphosts), " hosts alive\n\n";
    and remove the $#uphosts manipulation.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: how is this uninitialized?
by revdiablo (Prior) on Dec 28, 2004 at 18:11 UTC

    Another way to do it, other than the fine way shown by dragonchild:

    my $hodown = @downhosts; my $houp = @uphosts; print "There are $hodown hosts down\n"; print "There are $houp hosts alive\n\n";

    Sorry for the variable names, I couldn't resist. This has the benefit of allowing simpler interpolation in a string, and doesn't require the explicit use of scalar. It has the detriment of creating two superfluous variables. I am not necessarily advocating any particular solution, just giving another option. :-)

      Or, while we're giving alternatives:

      print <<"REPORT" There are @{[ scalar @downhosts ]} hosts down There are @{[ scalar @uphosts ]} hosts up The following hosts are alive: @{[ join "\n\t" => @uphosts ]} The following hosts are down: @{[ join "\n\t" => @downhosts ]} REPORT

      I like inline expansions, apparently perl6 is supposedly going to make that easier.

Re: how is this uninitialized?
by blazar (Canon) on Dec 28, 2004 at 19:33 UTC
    Why am I getting the following output when I use warnings?
    <SNIP>
    Use of uninitialized value in concatenation (.) or string at ./mship.pl line 33.
    Well, I'm in a hurry and I've not checked carefully the rest of this post and the answer you got. However it seems to me that you've been helped to track down that warning to something wrong you were doing. So indeed the warning has served its purpose.

    Said this, it may be worth mentioning that this particular warning is proably the one that most often can be locally disabled out of good reasons, i.e. you may have a situation in which you need to e.g. interpolate a variable which can possibly be undefined and you may want to let it be interpolated silently as the empty string. If you need cope with such a state of things, of course TIMTOWTDI, but a sensible one can be to include the warning generating line(s) in a block like this:

    { no warnings 'uninitialized'; # Do what you wanna... }

    Please note that I'm not suggesting this as a means to get rid of the warning the next time you'll encounter it. You should really use it only if you know in advance that you may receive that warning, but you don't want to be warned...