1
votes

So I am very new and inexperienced to the ways of TCL programming. I wrote a script that calls a proc written by someone else, first removing the output file. It then does some additional logic I wrote.

I moved the logic into a second proc and instantly a bunch of it broke (namely the rm commands).

From what I can tell, the first program on a line inside the central execution (the text following proc definitions) executes normally without an "exec" command. However, if you move it inside a proc, it now needs an "exec" command.

Can anyone explain to me why TCL behaves this way?

e.g.

proc helloworld {} {
  puts "hi"
}
#works
rm my_file 
helloworld

..

proc helloworld {} {
  #doesn't work
  rm my_file 
  puts "hi"
}
helloworld

..

proc helloworld {} {
  #works
  eval rm my_file 
  puts "hi"
}
helloworld

..

proc helloworld {} {
  #works
  file delete my_file 
  puts "hi"
}
helloworld

*Note this weird behavior may be specific to the program I'm feeding the script to vmd, which has its own built in TCL behavior. Perhaps in your responses you can indicate if this is standard for other interpreters as well?

2
file delete is preferable to exec rm ...glenn jackman
Yea, I switched all my statements to that to be more tcl-ish. I always try to use a scripting language's built in functionality versus common external programs, though there's typically many ways to skin the metaphorical feline. That seems like a good idea as it will make the code less platform/distribution dependent.Jason R. Mick

2 Answers

5
votes

An interactive tclsh session will try to exec an unknown command (such as rm). You cannot count on this behaviour in non-interactive script execution or, as you've discovered, in procs.

I can't see that this is documented in the tclsh man page, but the unknown man page does. See also the tclsh page on the Tcl wiki. In an interactive tclsh session, you can see what unknown does by typing:

info body unknown

[update]

Quoting from "Practical Programming in Tcl and Tk":

The unknown command provides a few other conveniences. These are used only when you typing commands directly. They are disabled once execution enters a procedure or if the Tcl shell is not being used interactively. The convenience features are automatic execution of programs, command history, and command abbreviation. These options are tried, in order, if a command implementation cannot be loaded from a script library.

2
votes

Note this is programatically testable too, via the variable tcl_interactive, which is "1" if the Tcl is being run via an interactive shell, and "0" if not. The variable is also settable, so one could start an interactive shell, then [set tcl_interactive 0], and continue on. At this point, one loses such features as

  • the % command prompt
  • proc name / command name completion (i.e.: can't type [pu "xyz"] and get the effect of typing [puts "xyz"], like an interactive shell)
  • automatic "shell-out" to have external commands complete a request (like the "rm" in this original question)
  • and perhaps others...