开发者

Weird TCL quirk

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

..

pro开发者_StackOverflow中文版c 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?


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.


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...

  • 0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新问答

    问答排行榜