in reply to A better understanding of while () loops
Note the use of && instead of ||. If you'd use || the condition would be true if $input was both 'good', 'bad' and 'iffy' at the same time. This can't happen.$input ne 'good' && $input ne 'bad' && $input ne 'iffy'
However, in your example, you don't need this test at all. You've already covered the cases for 'good', 'bad' and 'iffy', so by the time you get here, you already know $input isn't containing any of them. Write your chain as:
Now, if all you do is printing strings in your cases, you could have used a hash, and simple print the appropriate value from the hash, but that draws away into details not related to the control flow questions you have.if ($input eq 'good') {print "..."} elsif ($input eq 'bad') {print "..."} elsif ($input eq 'iffy') {print "..."} else {next} last;
Finally, your loop stinks. You have a while loop whose guard is always true, but then inside you read unconditionally from standard input. What if there's nothing more to read?
I would write that as:
Note that I preferred to repeat the 'last' in the various blocks, and that I got rid of the 'next' statement. This code stops processing input if there's no more input - that's what the while is doing.print "Are you having/had a good, bad, or iffy day $name?: "; while (my $input = <>) { chomp $input; if ($input eq 'good') {print "..."; last} elsif ($input eq 'bad') {print "..."; last} elsif ($input eq 'iffy') {print "..."; last} print "Are you having/had a good, bad, or iffy day $name?: "; }
Purists may object to the duplication of the code - the printing of the prompt happens twice. If so, one could use IO::Prompt or write something like:
But I prefer the duplication of code over the added complexibility.while (do {print "...."; defined (my $input = <>)}) { if (...) {...; last} elsif (...) {...; last} elsif (...) {...; last} }
|
|---|