in reply to Modifying loop structure and placement
There are three things that we want to accomplish in the first statement of the user command loop:
1. prompt the user
2. get some user input
3. decide whether we should stop the loop (like a quit, QuIt command or whatever).
In my opinion the most common condition that "ends the loop" should be apparent right in the looping statement, not buried later down as some "last" in the body.
Of course with all programming things there are judgments and I do use "last".
This is one of the few places where the "comma" operator is the right idea! If you look at my code below, the while() statement contains all three of the above things! We prompt the user, then get the input and check it against the "quit" command in various cases. The truth or falseness of the while() is determined by the last statement in the while. The use of the comma operator here also eliminates the use of multiple print statements to re-prompt the user. There are cases where "retry" is appropriate, but I don't think that this is one of them.
So now that we have prompted the user and gotten some input and decided that the program should continue, the user input data validation starts.
The first thing is that a blank line should do "nothing" except re-prompt. That's just like your OS does when you hit "enter" or "carriage return"! This is expected behaviour.
Now we proceed to perform various validation checks. Some of this stuff can become "order dependent" and I therefore prefer a simple if(condition){error msg;next} structure versus a more complex if,elseif,else type of deal. This allows the order of the conditions to be moved around easily and quite frankly the computation power that can be saved in a more complex "if" structure is absolutely meaningless.
Now of course there are standard programs like getOpt and the long option version of that. I don't think that we are talking about that here.
#!/usr/bin/perl -w use strict; #basic "command loop" while ( (print "Enter a command: "), (my $line = <STDIN>) !~ /^\s*q(uit)?\s*$/i ) { #### Validate input and if ok, call a sub at the #### of validation next unless $line =~ m/\S/; #chomp ($line); #actually optional here (\n counts as $) if ($line =~ m/^\s*help\s*$|^\s*h\s*$/i) { print "there is no help for the helpless!!!\n"; next; } if ($line =~ m/^\s*[+-]{0,1}\s*\d+\s*$/) { print "wow, a number! try again!\n"; next; } if ($line !~ m/^add$|^del$/i) { print "invalid_command!!\n"; next; } add() if $line =~ m/add/; del() if $line =~ m/del/; } sub add { print "some kind of add happend\n";} sub del { print "some kind of del happened\n";} __END__ Some example interaction: C:\TEMP>perl stdcommandloop.pl Enter a command: 34 wow, a number! try again! Enter a command: -45 wow, a number! try again! Enter a command: +-56 invalid_command!! Enter a command: Enter a command: Enter a command: help there is no help for the helpless!!! Enter a command: Enter a command: del some kind of del happened Enter a command: add some kind of add happend Enter a command: quit > (OS prompt is back, end of program)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Modifying loop structure and placement
by irvson (Sexton) on Dec 30, 2009 at 23:01 UTC |