Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

uninitialized values

by gaurav (Sexton)
on Aug 19, 2013 at 11:53 UTC ( [id://1050021]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,I know its something which I should not ask,but I tried a lot.So now I come to you people to help me out of this

I have written one Perl script to open ping process take its output , parse it and show its output

open CMD, "/bin/ping -c $count -i $interval -s $packetsize -w $allowab +leTime $host |" or die "Can't open ping: $!"; while (<CMD>) { my (@values1,@val1,@values2,@val2,$val) = 0; if ( $_ =~ /PING/ ){ @values1 = split ; @val1 = split(/\(/,$values1[3]); $val1[1] =~ s/\)//; } print "$values1[1] \n"; print "$val1[0] \n"; }

I want to print the last two prints outside if blocks but I am getting warning,I know its related to lexical variable ,but I couldn't figure it out.Warning is something like this :

Use of uninitialized value $val in concatenation (.) or string at ./pi +ng_linux.pl line 69, <CMD> line 2.

please help me out on this

Replies are listed 'Best First'.
Re: uninitialized values
by kcott (Archbishop) on Aug 19, 2013 at 12:29 UTC

    G'day gaurav,

    Your problem line is this:

    my (@values1,@val1,@values2,@val2,$val) = 0;

    While that declares all those variables, it only assigns 0 to @values1; the other four variables are all undefined. $var remains undefined and the other three arrays are still empty. [Update on that last clause thanks to AnomalousMonk.]

    If you're assigning values to the arrays elsewhere in your code (you only show assignments to @values1 and @val1 here), then you can do this:

    my (@values1, @val1, @values2, @val2); my $val = 0;

    That's a guess because you haven't shown enough of your code!

    Another separate problem is your choice of variable names. The names convey no meaningful information whatsoever (all variables can hold values) and, because they are so similar, they are highly error prone (for you, the developer) and highly problematic for any maintainer (whether you or someone else). I strongly recommend you change them to something meaningful.

    -- Ken

      Thanks Ken for pointing me out the faults I have committed,I would keep in mind.But then how can, I get those values outside If - block.And another thing is, that those variable names are only for testing purpose ,I just wanted to check that whatever I have been doing there is write or wrong .I will give them a meaningful name once I am done with it

        The warning you are getting is about $val. It's telling you that variable is uninitialised on line 69 in some concatenation or string operation.

        The warning has nothing to do with either of the print statements you show. I suspect you're already being tripped up by your poorly named variables! The first print statement has $values1[1], that's the second element (index 1) of the @values1 array; the other print statement has $val1[0], that's the first element (index 0) of the @val1 array. Except for the declaration of $val (i.e. my (..., $val) = 0;), that variable appears nowhere in the code you have posted.

        Please read "How do I post a question effectively?" then, following its guidelines, produce a minimal script that reproduces your problem. In creating a minimal script, you may well get some insights into whatever your problem is and be able to solve it yourself; if not, then post the minimal script that reproduces your problem and we can look at it further.

        "I will give them a meaningful name once I am done with it"

        Hopefully, it's now obvious to you that that's the wrong way to do it. Furthermore, consider honestly whether — once your code is written, tested and functioning correctly — you would actually go back and rewrite it. [That's something for you to consider privately to yourself: it's not a question I want an answer to here.]

        Give them meaningful names at the outset: write your code well once, then spend the remaining time on something more interesting than rewiting your code a second time. You're making a rod for your back if you do otherwise.

        -- Ken

Re: uninitialized values
by hippo (Bishop) on Aug 19, 2013 at 12:30 UTC

    Your arrays @values2 and @val2 and the scalar $val are never used, so let's remove them for now.

    The main problem is that your assignment to zero is almost certainly not doing what you want. It is setting @values1 to (0) and @val1 to undef. When the "if" expression is false, those values are not changed and so what you are attempting to print is undefined - hence the warning. To illustrate, try changing your loop like this:

    while (<CMD>) { my (@values1) = ('Not set', 'Really not set'); my (@val1) = ('Nothing here', 'Nor here'); # Nothing changed below here if ( $_ =~ /PING/ ){ @values1 = split ; @val1 = split(/\(/,$values1[3]); $val1[1] =~ s/\)//; } print "$values1[1] \n"; print "$val1[0] \n"; }

    I would also very strongly urge you to get into the habit of choosing meaningful names for your variables. @values1, @val1, @values2, @val2 and $val are all very similar and equally meaningless and this really adds to the confusion of the code.

    Good luck.

      Sorry ,for variable names & am very thankful to you for pointing that out to me.But my problem is remain same that I want to use those print stmt. outside if block,please help me on this

        ... I want to use those print stmt. outside if block ...

        The code example of hippo defines and initializes the lexical  @values1 and  @val1 arrays outside the if-block and then uses them both inside and outside the block. Please take another look at this example and see if things make more sense.

        I should ask that what I have to do to avoid that warning

Re: uninitialized values
by Random_Walk (Prior) on Aug 19, 2013 at 14:09 UTC

    You perform a test to see if you matched the line with PING, but then perform the print on every cycle. Is this script more like what you want?

    #!/usr/bin/perl use strict; use warnings; my $count = 1; my $interval = 5; my $pkt_size = 128; my $timeout = 5; my $phost = 'www.google.com'; open CMD, "ping -c $count -i $interval -s $pkt_size -w $timeout $phost + |" or die "Can't open ping: $!"; while (<CMD>) { # look for the line like: PING www.google.com (10.160.83.59): 56 d +ata bytes next unless /PING\s+(\S+)\s+\(([\d.]+)\)/; print "host: $1\n"; print "IP: $2\n"; }

    If you want to keep the values outside the loop: define the variable before the loop, then put the host/ip into the variables when you find them. Print at your leisure.

    #!/usr/bin/perl use strict; use warnings; my $count = 1; my $interval = 5; my $pkt_size = 128; my $timeout = 5; my $phost = 'www.google.com'; open CMD, "ping -c $count -i $interval -s $pkt_size -w $timeout $phost + |" or die "Can't open ping: $!"; my $host; my $ip; while (<CMD>) { # look for the line like: PING www.google.com (10.160.83.59): 56 d +ata bytes next unless /PING\s+(\S+)\s+\(([\d.]+)\)/; $host = $1; $ip = $2; } print "host: $host has IP: $ip\n";

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

      Thanks Random_Walk

Re: uninitialized values
by Laurent_R (Canon) on Aug 19, 2013 at 21:41 UTC

    Use of uninitialized value $val in concatenation (.) or string at ./ping_linux.pl line 69, <CMD> line 2.

    Your warning message is about an unitialized $val variable, but you are not using any such variable in the code you have posted (you're declaring one, but not using it).

    The waning message also mentions line 69 of your code, the code you display is about 15 lines. How do you expect us to tell you what is wrong in line 69 if you don't show it to us?

    Please give us line 69 of your code, or give us a correct warning message. You need to be very accurate on these types of things if you want us to be able to help. Please help us to help you.

    In addition to other problems indicated by others (and using meaningful variable names is really not a luxury, we could understand much better what you are trying to do if your variables names would tell us what they are intended to contain; to me using meaningful names for variables, subroutines, etc. is the most important form of code comment), I also doubt quite a bit that the following lines (at least the two last ones) do what you want:

    @values1 = split ; @val1 = split(/\(/,$values1[3]); $val1[1] =~ s/\)//;

    Please supply a sample of the ping command output, so that we can figure out what these code lines are supposed to do. Also you don't use $val1[1] after having assigned it, what's the point?

    BTW, the fact that you have this warning on line 2 possibly simply means that the second line of your input is empty.

      Sorry Laurent.Here below I am given my full code

      #!/usr/bin/perl -w =head1 NAME ping_linux.pl - This script works on Linux system pings a host and re +turns statistics data. =head1 VERSION Version 1.0 =head1 AUTHOR Gaurav Dubey (gaurav.d@ronankiinfotech.com =head1 SYNOPSIS ./ping_linux.pl [-c --> count (Number of echo requests to be sent)] +[-i --> interval (Interval in milliseconds between echo requests)] [ +-s --> packetsize (Size of icmp packet)] [-h --> destinationIP (Ip ad +dress of destination host)] [-w --> AllowableTime (Max time in second +s for sending receiving echo requests/reponse)]" =head1 DESCRIPTION This pings a host via the system ping command and returns RTA ,Tx pack +ets,Rx packets,TTL,Packet-loss =cut use strict; use Getopt::Long; use Pod::Usage; my ($host,$count,$interval,$packetsize,$allowableTime); GetOptions( "h|host=s", \$host, "c|count=i", \$count, "i|interval=i", \$interval, "s|packetsize=i", \$packetsize, "w|allowableTime=i",\$allowableTime, ); #pod2usage("$0: No host given!\n") unless($host); pod2usage("$0:No host given!\n") unless($host && $host =~ /^((([2][5][ +0-5]|([2][0-4]|[1][0-9]|[0-9])?[0-9])\.){3})([2][5][0-5]|([2][0-4]|[1 +][0-9]|[0-9])?[0-9])$/); $count = 5 unless ($count); $interval = 1 unless ($interval); $packetsize = 56 unless ($packetsize); $allowableTime = 10 unless ($allowableTime); open CMD, "/bin/ping -c $count -i $interval -s $packetsize -w $allowab +leTime $host |" or die "Can't open ping: $!"; while (<CMD>) { my (@values1,@val1,@values2,@val2); if ( $_ =~ /PING/ ){ @values1 = split ; @val1 = split(/\(/,$values1[3]); $val1[1] =~ s/\)//; } print "$values1[1] \n"; print "$val1[0] \n"; if ($. == 2) { @values2 = split; @val2 = split(/\=/ , $values2[5]); } print "$val2[1] \n"; } close CMD

      by this means I am running my perl script

      ./ping_linux.pl -h 74.125.235.7  -c 1

      And this is my output

      74.125.235.7 56 Use of uninitialized value $val2[1] in concatenation (.) or string at +./ping_linux.pl line 64, <CMD> line 1. Use of uninitialized value $values1[1] in concatenation (.) or string +at ./ping_linux.pl line 58, <CMD> line 2. Use of uninitialized value $val1[0] in concatenation (.) or string at +./ping_linux.pl line 59, <CMD> line 2. 54 Use of uninitialized value $values1[1] in concatenation (.) or string +at ./ping_linux.pl line 58, <CMD> line 3. Use of uninitialized value $val1[0] in concatenation (.) or string at +./ping_linux.pl line 59, <CMD> line 3. Use of uninitialized value $val2[1] in concatenation (.) or string at +./ping_linux.pl line 64, <CMD> line 3. Use of uninitialized value $values1[1] in concatenation (.) or string +at ./ping_linux.pl line 58, <CMD> line 4. Use of uninitialized value $val1[0] in concatenation (.) or string at +./ping_linux.pl line 59, <CMD> line 4. Use of uninitialized value $val2[1] in concatenation (.) or string at +./ping_linux.pl line 64, <CMD> line 4. Use of uninitialized value $values1[1] in concatenation (.) or string +at ./ping_linux.pl line 58, <CMD> line 5. Use of uninitialized value $val1[0] in concatenation (.) or string at +./ping_linux.pl line 59, <CMD> line 5. Use of uninitialized value $val2[1] in concatenation (.) or string at +./ping_linux.pl line 64, <CMD> line 5. Use of uninitialized value $values1[1] in concatenation (.) or string +at ./ping_linux.pl line 58, <CMD> line 6. Use of uninitialized value $val1[0] in concatenation (.) or string at +./ping_linux.pl line 59, <CMD> line 6. Use of uninitialized value $val2[1] in concatenation (.) or string at +./ping_linux.pl line 64, <CMD> line 6.

      So now please enlighten me on this .Thanks

        Here's a way to get rid of the warnings, but really you need to reconsider the whole approach used in the while loop. That code is a mess.

        By declaring lexical variables inside the loop, they get reset each time through. Move the declarations out of the loop for them to persist.

        my (@values1,@val1,@values2,@val2); while (<CMD>) { ...
        You will still get one warning from line 1, because the code after the if loop is executed for all lines and @val2 is not yet defined. Adding next can fix that.
        my (@values1,@val1,@values2,@val2); while (<CMD>) { if ( $_ =~ /PING/ ){ @values1 = split ; @val1 = split(/\(/,$values1[3]); $val1[1] =~ s/\)//; next; } ...

        Again, while these changes avoid the warnings and hopefully show you why they happened, the entire while loop needs a rethink.

        If you have not looked at it already, you may want to take a look at Net::Ping. that way you avoid a lot of system dependencies. On the down side there are limits to the sort of ping you can perform on Unix, unless you are running as root

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1050021]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2024-04-18 09:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found