Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

uninitialized value in phonebook program

by smgfc (Monk)
on Feb 25, 2002 at 03:15 UTC ( #147256=perlquestion: print w/replies, xml ) Need Help??

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

So I am about switch phones, but panasonic cant get the 200+ phone numbers I have saved on my phone to the new one, so I wrote this program to create a text file of all the names in the phone book and their numbers, that way i can create a program to parse the output and (granted manually) enter them into the new one.The problem, however, is some numbers in my phone book only have a first name, not a first and a last, (i.e. "Doctor" or "school") and so I assign a 0 to that field. When I go to write the data I get a uninitialized value error at line 45 if ($2 =~ /^0$/) {, which doesnt make any sense to me since $2 is defined as 0. Anyway here is the code, if anyone has a clue what is going on, thanks alot! thans alot anyway
#!/usr/bin/perl -w use strict; my (@def, %char, $cont, $field, @info, %book, $file, $name, $i); @def = qw\ first_name second_name work_number home_number cell_number +\; #fields %char = ( #regex for each field 'first_name' => '^[a-z]+$', 'second_name' => '^[a-z]*$', 'work_number' => '^([0-9]{3}-|)[0-9]{3}-[0-9]{4}$', 'home_number' => '^([0-9]{3}-|)[0-9]{3}-[0-9]{4}$', 'cell_number' => '^([0-9]{3}-|)[0-9]{3}-[0-9]{4}$' ); $cont = 1; while ($cont == 1) { @info = (); foreach $field (@def) { print "$field: "; $_ = <>; chomp; unless ($_) { #if no input then field = 0 push @info, "0"; next; } while (!/$char{$field}/i) { #check format print "error: $_: invalid format: $char{$field}\n"; print "$field: "; $_ = <>; chomp; unless ($_) { push @info, "0"; next; } } push @info, lc($_); } for (2 .. $#info) { #create hash of array of data, key = first nam +e & last name push @{ $book{$info[0] . "&" . $info[1]} }, $info[$_]; } print "another entery? (*/n)"; $_ = <>; chomp; $cont = 0 if /n/i; } print "Save where? "; $file = <>; chomp $file; open (BOOK, ">$file") or (die "Can't open $file: $!"); foreach $name (keys %book) { #write the data $name =~ /(.+)&(.+)/; if ($2 =~ /^0$/) { print BOOK "$1,::"; } else { print BOOK"$1,$2::"; } for ( 0 .. $#{ $book{$name} } ) { print BOOK $def[$_+2] . ":" . $book{$name}[$_] . "::" unless +$book{$name}[$_] =~ /^0$/; #print field name then data unless the fie +ld is empty } print BOOK "\n"; } close(BOOK);

Edit: chipmunk 2002-02-24

Replies are listed 'Best First'.
Re: uninitialized value in phonebook program
by chipmunk (Parson) on Feb 25, 2002 at 03:37 UTC
    I noticed two problems in your code. First, the line where you're getting the warning:
    $name =~ /(.+)&(.+)/; if ($2 =~ /^0$/) {
    You haven't actually verified that the regex matched against $name. I suspect that the regex match is failing, leaving $1 and $2 uninitialized, because $name doesn't hold what you think it does. Make sure the match succeeds before relying on the special variables.

    Second, to check the format, you have a while loop inside your foreach loop. If $_ is false, you push 0 onto @info, and then call next. However, this next jumps to the next iteration of the while loop (which would happen anyway), when you want to jump to the next iteration of the foreach loop. You should use a loop label to resolve this problem.

      when you change the code to print out the values of $name, $1, and $2:
      foreach $name (keys %book) { #write the data print "$name \n"; $name =~ /(.+)&(.+)/; print "$1, $2 \n"; if ($2 =~ /^0$/) { print BOOK "$1,::"; } else { print BOOK"$1,$2::"; } for ( 0 .. $#{ $book{$name} } ) { print BOOK $def[$_+2] . ":" . $book{$name}[$_] . "::" unless +$book{$name}[$_] =~ /^0$/; } print BOOK "\n"; }
      you get the correct output, and it shows $1 and $2 are initialized, but you still get the uninitialized error. Here is the output when you pass it School&0 and one number:
      
      school&0
      
      school, 0 
      # Use of uninitialized value, <> chunk 7.
      File 'untitled:Desktop Folder:Will's Stuff:Applications:MacPerl :phonebook'; Line 57
      
      so that isnt the problem. Loop lables are a good idea, though, thanks
        Oh, now I got it! The warning is not actually coming from the if ($2 =~ /^0$/) { line. Unfortunately, perl sometimes reports the line number where an if block starts when the warning actually occurs later in the block. That's what is happening here.

        First, you perform a regex match against $name, setting $1 and $2. Then, you perform a regex match against $2. So far, so good. Then you print out the values of $1 and $2. Oops! That second regex match you just did has wiped out the values of $1 and $2!

        jeffa's node shows two ways to solve this problem. Either assign the results of the first match to new variables: my($first, $last) = $name =~ /(.+)&(.+)/; Or replace the second match with a comparison: if ($2 eq '0') {

(jeffa) Re: uninitialized value in phonebook program
by jeffa (Bishop) on Feb 25, 2002 at 03:34 UTC
    If you think about it for a second, /^0$/ is really the same thing as == 0 eq '0' (thanks chipmunk!) ... here is some code for you to meditate upon:
    use strict; my $name = 'school&0'; my ($first,$last) = $name =~ /(.+)&(.+)/; print "$first:$last\n"; print "== is true\n" if $last == 0; print "eq is true\n" if $last eq '0'; print "=~ is true\n" if $last =~ /^0$/;

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      update: you are totally right however, about using eq '0', i should have read your node a little more closely! sorry :)

      the problem with using == instead of /^0$/ is that what if the input is "william&meyer" instead of "school&0"? if you use == on meyer ($2) then you get a warning about context (== on a string), whereas if you use /^0$/ you dont have to worry about wether $2 is a string (meyer) or a number (0)
Re: uninitialized value in phonebook program
by Anonymous Monk on Feb 25, 2002 at 05:09 UTC
    I dunno but maybe instead of putting 0 in where you
    don't know the last name (or whatever) why not put
    ZERO or NULL or UNKNOWN? Will that solve your immediate
    problem?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2021-04-23 03:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?