in reply to Re: Resetting variables
in thread Resetting variables

I'll reply to all of you that told me to use strict and warnings. I am doing that, and my code runs without errors or warnings the first pass. I also have lots of lexical scoping throughout my code, but I couldn't think of a better way to keep the variables I needed so I could use them in all the various subs and such. I tried passing paramaters and other things like that, but I kept getting 'unitialized' errors, so I went back to the global way. I have read perlintro about 50 times, and lots and lots of other documentation, but I'm still learning and making a lot of dumb mistakes. BTW, this game is not finished, and I haven't added in most of the data that I want the game to keep track of between runs (ex. a word list and related logic).

Obviously this is a case of not enough code, so here is my entire script:

use strict; use warnings; ###################### ###################### ## Main Program ## ###################### ###################### my $word = "toast"; my @word_array = split //, $word; my $word_len = length($word); print "\n"; my $found_one = 0; my $guessed_word = 0; my ($guess, $good_guesses, $bad_guesses); my ($tot_found, $occurrences, $all_occurrences) = 0; while ($word_len >= $tot_found) { if ($word_len == $tot_found) { print_word(); print "\nYou've guessed the word!\n"; play_again(); } else { print_word(); if ($guessed_word == 0) { get_guess(); check_guess(); } else { play_again(); } } if ((defined($bad_guesses))&&(length($bad_guesses) == 5)) { print "\nYou've had 5 bad guesses. GAME OVER\n\n"; print "The word was \"$word\"\n"; last; } } ###################### ###################### ## Sub Routines ## ###################### ###################### ################ # print_word # ################ sub print_word { print "\nIncorrect: $bad_guesses\n" if defined($bad_guesses); print "\n"; if ((defined($found_one))&&($found_one == 0)) { for (my $i=1; $i<=$word_len; $i++) { print " _ "; } print "\n"; } else { for (my $i=0; $i<$word_len; $i++) { if ($i =~ /[$all_occurrences]/) { print " $word_array[$i] "; } else { print " _ "; } } print "($word_len letters) ($tot_found found)\n\n"; if (($word_len > $tot_found)&&($tot_found > $word_len/2)) { print "Do you want to guess the word (y or n)? "; my $response = <STDIN>; chomp($response); early_guess() if ($response eq "y"); } } } ############### # get_guess # ############### sub get_guess { print "\nGuess a letter: "; $guess = <stdin>; chomp($guess); print "\n-----------------------------------------\n"; } ################# # check_guess # ################# sub check_guess { my $occurrences = ""; my $guess_len = length($guess); print "\n$guess\n"; if ($guess !~ /[[:alpha:]]/) { print "\n***Invalid letter*** (hit any key)\n"; <>; } elsif ($guess_len > 1) { print "\n***Only one letter please!*** (hit any key)\n"; <>; } elsif ((defined($good_guesses))&&($guess =~ /[$good_guesses]/)) +{ print "\n***You already guessed that letter!*** (hit any key)\ +n"; <>; } else { if ($word =~ /[$guess]/) { if (defined($good_guesses)) { $good_guesses .= "$guess" unless ($guess =~ /[$good_gu +esses]/); } else { $good_guesses .= "$guess"; } my $ct = 0; foreach my $element (@word_array) { if ($element eq $guess) { $occurrences .= "$ct"; } $ct++; } $found_one = 1; } else { if (defined($bad_guesses)) { $bad_guesses .= "$guess" unless ($guess =~ /[$bad_gues +ses]/); } else { $bad_guesses .= "$guess"; } } $all_occurrences .= $occurrences; $tot_found = length($all_occurrences); } } ################# # early_guess # ################# sub early_guess { print "Your guess: "; my $word_guess = <STDIN>; chomp($word_guess); if ($word_guess eq $word) { print "\nYou've guessed the word!\n"; $guessed_word = 1; } else { print "\nYou guessed wrong (hit any key)"; <>; } return $guessed_word; } sub play_again { print "Do you want to play again (y or n)? "; my $play_again = <STDIN>; chomp($play_again); if ($play_again eq "y") { reset_game(); } else { last; } } sub reset_game { ($good_guesses, $bad_guesses) = ""; ($tot_found, $found_one, $occurrences, $all_occurrences, $guessed_ +word) = 0; }

Replies are listed 'Best First'.
Re^3: Resetting variables
by davido (Cardinal) on Dec 21, 2004 at 18:00 UTC

    The particular bug that's causing the error message you're referring to is in the reset_game() sub.

    The problem is that you're assigning a single scalar value '0' to a list. That means that $all_occurrences becomes undefined. Use an undefined value within a character class in a regexp and you get an error message. Try the followng:

    perl -e "my $var; 'string'=~/[$var]/"

    And here's the error...

    Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE ]/ at -e line + 1.

    If you're getting warnings when running under warnings and strictures, the goal is to understand why. The warnings are telling you something. In this case, you mentioned getting uninitialized value warnings. Instead of fixing the problem, you subverted the warnings, and that allowed bugs to creep in. If you had dug into why you were getting those undefined value warnings, you would have tracked the problem down to your reset sub.


    Dave

      Oops! I pasted an older version of my code...at one point I had that sub coded like this, but went to this incorrect way (as I now understand) to try to fix bugs.
      sub reset_game { ($good_guesses, $bad_guesses) = ""; $tot_found = 0; $found_one = 0; $occurrences = 0; $all_occurrences = 0; $guessed_word = 0; }

        Oops indeed. I spent time on that for you.

        Once again I don't know what your current code looks like. The code you posted above does give the error message you described, for the reason I described. Your newly posted reset_game() sub will not generate the same error, but still contains a bug. Hint: Why are you putting [$all_occurrences] within a character class to check what the user entered, when you've assigned a value of '0' to $all_occurrences? What is that supposed to do?


        Dave