Re: comparison of character
by roboticus (Chancellor) on Jul 16, 2013 at 11:14 UTC
|
Think about it a bit more: If the user enters 'X', it enters the while loop because 'X' ne 'Y', right?
If the user enters 'Y' then the first bit of your conditional fails ('Y' eq 'Y') so it continues to the next bit--but 'Y' ne 'y' so the conditional is satisfied anyway.
Any character you enter will satisfy one of the parts of your while condition. I suggest you think about your logic AND change the conditional to make it do what you want. ;^)
...roboticus
When your only tool is a hammer, all problems look like your thumb.
| [reply] [Watch: Dir/Any] |
Re: comparison of character
by choroba (Cardinal) on Jul 16, 2013 at 11:16 UTC
|
If you enter "Y", then $choice ne "N", so the OR clause is true and the while loop continues. You should have used && instead of ||.
Moreover, you can include the first reading of the input into the loop as well:
print "Do you wish to update (Y/N)?\n";
my $choice = q();
while ('y' ne lc $choice and 'n' ne lc $choice) {
chomp($choice = <>);
}
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: comparison of character
by moritz (Cardinal) on Jul 16, 2013 at 11:15 UTC
|
Your loop misses a body (with curly braces).
$choice ne "Y" || $choice ne "y"
if $choice is Y, then $choice ne 'y' is true, and the whole condition is true. Or more general, if one of the branches is false, all the other branches are true, and the condition as a whole is true again.
You probably want to use while ($choice !~ /[yn]/i) { ... }, or while (!($choice eq 'y' || $choice eq ...)) { }.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: comparison of character
by rjt (Curate) on Jul 16, 2013 at 11:39 UTC
|
A couple other points to ponder:
print "Do you wish to update (Y/N)?\n";
You likely added the \n to ensure the prompt prints for the user. See $| to print without buffering, so you don't need the trailing newline:
$| = 1;
print "Do you wish to update (Y/N)? ";
The overall structure leaves a bit to be desired. What about something more along these lines?
$| = 1;
my $choice;
do {
print "Do you wish to update (Y/N)? ";
$choice = lc <>; chomp $choice;
} until ($choice =~ /^[yn]$/i);
say "You picked `$choice'";
This will repeat the prompt if the input is invalid, and normalizes the input by converting it to lowercase, to simplify your code later in the program. | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: comparison of character
by davido (Cardinal) on Jul 16, 2013 at 15:57 UTC
|
If it's homework, by all means, figure out the logic. If not:
use IO::Prompt::Hooked;
my $choice = prompt(
message => 'Do you wish to update? (Y/N):',
validate => qr/^[YN]$/i,
);
Or if you want to provide extra help upon receiving invalid input:
my $choice = prompt(
message => 'Do you wish to update? (Y/N):',
validate => qr/^[YN]$/i,
error => "Response must be 'Y' or 'N'.\n\n",
);
...or if you want to add a default...
my $choice = prompt(
message => 'Do you wish to update? (Y/N):',
default => 'N',
validate => qr/^[YN]$/i,
error => "Response must be 'Y' or 'N'.\n\n",
);
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: comparison of character
by hippo (Bishop) on Jul 16, 2013 at 11:14 UTC
|
Just amend your code to display the value of $choice so you can see what it really is. Do this just before you test it. eg.
print "The value of \$choice is '$choice'\n";
while ($choice ne ...
| [reply] [Watch: Dir/Any] [d/l] |
Re: comparison of character
by BillKSmith (Monsignor) on Jul 16, 2013 at 15:05 UTC
|
I recommend that you use a module to prompt. Under ActiveState, use ActiveState::Prompt. It has a function called 'yes' whic does what you want. On other platforms, use IO::Prompt::Hooked. The documentation uses your case as an example of prompt with validation.
| [reply] [Watch: Dir/Any] |
Re: comparison of character
by Anonymous Monk on Jul 16, 2013 at 11:21 UTC
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
No. According to perlop, eq has a higher precedence than || and or, so, in this case, either one will do the same thing.
I tend to use || for logical tests (X || Y) and or for flow control (STMT or die...).
Update: clarified word choice a bit.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
probably because you used || instead of or its (...) || (...) ... or ... or ... or ...
As already pointed out by others, it should really be a logical and, not a logical or.
| [reply] [Watch: Dir/Any] |
|
As already pointed out by others, it should really be a logical and, not a logical or. AND IM SLEEPY WRONG FOOL 20min ago, not every foolish post needs multiple followups :)
| [reply] [Watch: Dir/Any] |
|
|
| [reply] [Watch: Dir/Any] |