http://www.perlmonks.org?node_id=242633

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

Howdy Y'all,

I'm fairly n00b at Perl here, so go easy on me. I am encountering an interesting problem that I have as yet not run across in my short experience.

It works thus: while I am validating user input with a basic do-while loop
$i=0; do { print "Not an option!\n" if $i>0; print "Are you to proceed? (y/n): "; chomp($make_account = <STDIN>); ++$i; die "\nCiao!\n" if (($make_account eq 'n') || ($make_account e +q 'N')); } while ( ($make_account ne 'y') || ($make_account ne 'Y') );
For some reason, the while loop does not accept *any* input (that is, 'y' or 'Y') as being valid? And yet an slightly altered form of the input check in the form of an if statement works fine. Please, any help would greatly ease my mind!

Thanks in advance.

Replies are listed 'Best First'.
Re: do-while loop question
by bart (Canon) on Mar 13, 2003 at 10:17 UTC
    Simple. Replace the "||" in your condition with "&&".
    } while( ($make_account ne 'y') && ($make_account ne 'Y') );

    Now, it's not possible for something to be the same as 'y' and as 'Y' at the same time. Thus, always at least one of the subconditions will be true.

    Alternatively, using De Morgan's equivalences, you could replace the last line with

    } until ( ($make_account eq 'y') || ($make_account eq 'Y') );
Re: do-while loop question
by grinder (Bishop) on Mar 13, 2003 at 11:02 UTC

    You could do away altogether with your 'this or that' conditional by simply using:

    do { ... } while lc($make_account) ne 'y';

    or

    do { ... } while $make_account !~ /^\s*y/i;

    ... so that if they accidently lean on the space bar it will ignore the spaces (and tabs)...


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
Re: do-while loop question
by vagnerr (Prior) on Mar 13, 2003 at 10:25 UTC
    You are nrealy there, your Boolean logic is just alittle off. what you need is
    while ( ($make_account ne 'y') && ($make_account ne 'Y') );
    ie && rather than ||
    Hope this helps

    _______________________________________________________
    Remember that amateurs built Noah's Ark. Professionals built the Titanic.
Re: do-while loop question
by virtualsue (Vicar) on Mar 13, 2003 at 11:33 UTC
    I never loop on simple yes/no answer questions. It's unnecessarily complex and doesn't usually add much value to a program. In your example, I would only accept an answer starting with Y/y and die if any other input value was detected. For example:
    print "Are you ready to proceed? [y/N]: "; chomp(my $answer = <STDIN>); die "Ciao!\n" if ($answer !~ /^y/i);
    Now 8 lines of somewhat torturous logic have been reduced to 3 simple statements.

      Quite true. But then again, if you're only looking at the beginning of the string, chomping becomes superfluous, and you don't even need to spring a variable into existence:

      print "Are you ready to proceed? [y/N]: "; <STDIN> !~ /^y/i and die "Ciao!\n";

      I changed the structure of the second line because it seems to read better to me, don't shoot me, it's a question of style. So now we have one line down, two to go :)


      print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

        I can throw it down to one line :)

        print "Are you ready to proceed? [y/N]: " and <> =~ /^y/i or die "ciao +\n";


        If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.