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

First the code:

print "Question #1: Who is buried in Grant's tomb?\n\n"; print "A. Grant\n"; print "B. Yoda\n"; print "C. Liberace\n"; print "D. None of the above.\n\n\n\n"; print "The answer is: "; chomp($reply = <STDIN>); #Following loop to test for a-d answers, courtesy of PerlMonks.org. #This works but will not accept any answer without going thru this #code block once print "\nPick a letter between a and d.\n"; chomp(my $reply = <STDIN>); while ($reply !~ /^[a-d]$/i) { print "\nPick a letter between a and d -- or else!\n"; chomp($reply = <STDIN>); }

If you've read the comments, you know what I can't fix. The code that I got here at Perlmonks does the job, but no response to the question will be accepted until that "while" loop runs once. When I asked for help a couple of weeks ago, I didn't include the code that showed the question. Maybe that would have made a difference. So, the question now is: How can I make sure that the answer to the question shown in the code is in the range a-d without showing the warning "Pick a letter between a and d" when the answer falls in the proper range?

Replies are listed 'Best First'.
Re: while loop almost correct
by Perlbotics (Archbishop) on Nov 15, 2009 at 01:06 UTC

    Your script ignores the the first $reply given.

    • First, remove the first chomp($reply = <STDIN>); before(!) the comment #Following loop....
    • Then, you might want to remove the first Pick a letter between a and d. print statement (outside the loop) - if that still bothers you (it is not clear to me from your question / personally, I would let it stay that way).
    HTH

Re: while loop almost correct
by toolic (Bishop) on Nov 15, 2009 at 01:31 UTC
    This is a style point, completely unrelated to your question...

    When I see a bunch of print statements, I automatically think HERE-DOC:

    print <<EOF; Question #1: Who is buried in Grant's tomb? A. Grant B. Yoda C. Liberace D. None of the above. The answer is: EOF

      Thanks. Problem solved. As is probably obvious from the question I posed, I'm just beginning to learn Perl. And I appreciate the style point. I'll take ALL suggestions. I wanted to eliminate that first "Pick a letter between a and d" because the question presents only those four choices. From my teacher's point of view, that extra "warning" seems unnecessary.

Re: while loop almost correct
by JadeNB (Chaplain) on Nov 15, 2009 at 07:25 UTC
    As Perlbotics points out, you are actually getting $reply twice, once on (non-blank) line 7, and then again on (non-blank) line 12. The $reply on line 7 is discarded. If you give a satisfactory reply on line 12, then the while loop doesn't actually run at all, as you would expect; you can tell this by noting that the or else! warning never appears.
      Thanks. I'm learning.
Re: while loop almost correct
by biohisham (Priest) on Nov 15, 2009 at 13:52 UTC
    Hashes are good for this sort of work, the question number is the hash key and the answer is the hash value related to that key, read this intro as well, there are many ways to declare a hash, here I assigned an array to a hash...the program uses a label called "CHECK" to control its flow...If the letter choice corresponds to a key in the hash then that hash value would be defined and you would see the answer, else the program would go back to the label "CHECK:" and prompt you to answer the question once again..
    use strict; use warnings; my @array = qw(a Grant b Yoda c Liberace d None); my %hash= @array; CHECK: print "Who's Buried in Grant's Tomb\n"; print <<ENDING; a. Grant b. Yoda c. Liberace d. None of the above. ENDING while(chomp(my $answer = <STDIN>)){ if(defined $hash{$answer}){ print "your Answer is \"$hash{$answer}\".\n"; print "Thank You.\n"; #do anything with the Answer.... exit; }else{ print "Please Pick a letter between A - D\n"; goto CHECK; } }


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
      Hashes are good for this sort of work, the question number is the hash key and the answer is the hash value related to that key
      Any time you find yourself thinking of using a number as a key into a hash, you should probably think about whether you mean to be using an array instead. In this case (but not every case: a sparse array is better implemented as a hash, if I'm not mistaken), I think that the answer would be ‘yes’.

      Nice! Whole different approach. I've gotten far enough in my Perl "studies" (learning on my own; lots of programming experience with other languages) to know what a hash is. Never would have occurred to me to use it here. Thanks.

      I'd like to pursue this suggestion. I guess what prompts me most is the "goto." I remember from my days in learning BASIC (couple of decades ago) that "goto" could be handy or deadly -- depending on how it was used. What topic do I pursue in order to learn more about the "CHECK" and "ENDING" code?

Re: while loop almost correct
by Anonymous Monk on Nov 17, 2009 at 10:15 UTC
    You may want to look at IO::Prompt.
    use IO::Prompt; my $reply = prompt("Pick a letter between a and d.\n", -r => { "Pick a letter between a and d -- or else!\n" => qr/^[a-d]$/i } );

      Thanks. Something else to learn. That's why I'm here.