views:

68

answers:

2

I am basically trying to return from a method which reads user input from the standard input stream. Since the user has the option to quit the application, I am trying to figure out the best way to do this exit. Ideally I will be able to return from begin() and let main() finish, thus quiting the applicaiton.

public static void main(String[] args) {
     begin();
}

private static void begin(){
     Machine aMachine = new Machine();
     String select=null;
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     while(true){
      try {
       select = br.readLine();
      } catch (IOException ioe) {
       System.out.println("IO error trying to read your selection");
       return;
      }catch(Exception ex){
       System.out.println("Error trying to evaluate your input");
       return;
      }

      if (Pattern.matches("[RQrq1-6]", select)) {
       aMachine.getCommand(select.toUpperCase()).execute(aMachine);
      }
      else {                
       System.out.println(aMachine.badCommand()+select);
       aMachine.getStatus();
      }
     }
    }

The main logic takes place when aMachine executes a given command by the user with this method:

aMachine.getCommand(select.toUpperCase()).execute(aMachine);

Again, the issue is how to quit the application once the user enters the command Q, or q. The quit command is like this:

public class CommandQuit implements Command {

    public void execute(Machine aMachine) {
     aMachine.getStatus();
     return; //I would expect this to force begin() to exit and give control back to main()
    }
}

Now following the advice from my previous question, to quit the application, I am trying to return to main() and basically let main() complete. This way I avoid any use of System.exit(0), although that would be fine too.

So, in this example, I have a return statement in the execute method of the CommandQuit class which is called when we receive a Q, or q from the user. However, when begin() executes a quit command, instead of returning from the while(true) loop, out of begin(), and back into main(), the control flow never seems to respond to the return; within the execute method of CommandQuit.

Is there anything that I am missing in my example? Perhaps something is so obvious that I can't see it at the moment. Thanks for any help.

+3  A: 

The return statement in execute() returns from execute(), not begin(). Usually in these cases, CommandQuit.execute() sets a flag on aMachine, and then begin() checks the flag at the top of the loop:

while (aMachine.stillRunning()) {  // instead of while (true)
    ...
    // This will clear aMachine.stillRunning() if the user quits.
    aMachine.getCommand(select.toUpperCase()).execute(aMachine);
}
Grandpa
A: 
return;

always returns from the current function only (in this case CommandQuit.execute). It's exactly the same as executing past the end of the function. You could set a flag in aMachine, and make the while loop run until it's set instead of running forever:

in the class "Machine" you would have:

    private boolean isRunning = false;
    public boolean stillRunning() {
        return isRunning;
    }
    public void stopRunning() {
        isRunning = false;
    }

and you would loop while aMachine.stillRunning() and call aMachine.stopRunning() to stop it.

immibis
Thanks for both the answers. Lesson learned!
denchr