Tcl: Use commandloop to Provide Interactive Access to Your Procedures

When I wrote text base programs in high-level programming languages, I often need to create a simple menu, get the user’s choice, then dispatch the appropriate procedure. The dispatch code often include lengthy swich (case) statement:

    switch (choice) {
	case 'a':
	case 'b':

This design pattern was fine if the menu is relatively short. As the menu grows, adding a choice to the menu means: 1) Add lines to the menu, 2) update the switch statement, and 3) write another function to handle the new choice.

This design pattern bears several problems:

  1. Adding an additional choice to the menu requires a lot of works as illustrated
  2. Programmer must take care to keep the menu and the switch statement in sync.
  3. As the menu grows, the switch statement can get very long

Fortunately, Tcl offers an easy remedy to this problem: commandloop. I wrote about commandloop before as my way to setup a break point for debugging purpose. Commandloop can do more than that. In this case, I can commandloop to provide dispatch to my procedures. Consider the following simple script:

	package require Tclx

	set stack {}

	proc stack {} { set ::stack }
	proc push {item} { lappend ::stack $item }
	proc pop  {}     { 
		set item [lindex $::stack end]
		set ::stack [lreplace $::stack end end]
		return $item


This script simulates a stack; it provides three commands (procedures): stack to display the contents of the stack and the self-explanatory push and pop. The script’s main body consists of a single commandloop command. So how does this works?

The commandloop command allow the users to interact with the script, including the ability to call the script’s commands. Let’s take a look at an interactive session:

    $ ./commandloop1.tcl 
    %push 5
    %push 7
    5 7 
    %push -3
    5 7 -3
    5 7 -3
    5 7 
    %set x 0 
    %push $x
    5 7 0 
    %puts "Stack contents: [stack]"
    Stack contents: 5 7 0 

After launching the script, we arrive at the ‘%’ prompt. From there, we can issue the script’s commands such as stack, push, and pop. Not only that, we can also set additional variables (such as x). We can all issue other commands such as puts. In short, the commandloop command opens up an interpreter to interact with the script. Finally, the exit command (or Ctrl-D in Linux, Ctrl-Z in Windows) exits the command loop and ends the script.

Commandloop comes with some handy optional flags. The first is the -endcommand flag. This flag specifies a command (or procedure) to execute after commandloop terminates. Note that after commandloop terminates, the script’s execution will stop, ignoring any command that follows. If you want to execute a command after the commandloop terminates, use this flag.

Another flag of interest is the -prompt1 flag. This flag allows the users to customize the prompt if they don’t like the default one. These are the two flags I use most often. For information regarding other flags, you can look up information for commandloop in the Tclx package.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s