admin管理员组

文章数量:1122832

There are a variety of ways I could implement include guards in TCL, but this is probably the most robust way I've considered, without knowing any tricks or shortcuts:

if { ! [info exists _THIS_FILE_] } { 
  set _THIS_FILE_ 1 
  # ...
}

However, it's verbose and introduces an indent on everything.

There are a variety of ways I could implement include guards in TCL, but this is probably the most robust way I've considered, without knowing any tricks or shortcuts:

if { ! [info exists _THIS_FILE_] } { 
  set _THIS_FILE_ 1 
  # ...
}

However, it's verbose and introduces an indent on everything.

Share Improve this question asked Nov 22, 2024 at 21:56 ChrisChris 31.2k31 gold badges97 silver badges186 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

There are several possibilities. The one closest to your proposal, but without introducing indentation of all the code would be:

if {[info exists _THIS_FILE_]} return
set _THIS_FILE_ 1
# ...

The source command will cease script evaluation when it encounters a return command.

However, I personally prefer to write my source files in such a way that they can harmlessly be sourced multiple times. This makes it easy during development to change the code and then load the updates in an already running program.

I suppose the proper way to do what you seem to be looking for is to turn files that you may want to include from multiple places into modules. This just means that you follow some rules for naming the files and place them in a directory on the module path (tcl::tm::path list), or adjust the module path to include the directory where your files are (tcl::tm::path add $dir/mylib). Then you can just package require the module in all the places where you would previously source your files. Tcl will take care of only loading each module once, so no further administration by the module developer is needed.

The source command is far too simple-minded to do this for itself; it really is just reading the file in and evaluating the contents immediately as a script. Instead, make the file into a package (by adding package provide myPkg 1 to the file and creating a pkgIndex.tcl to go with it). Then you get the only-once semantics when you package require it (unless you package forget it).


Alternatively, put this at/near the top of your script:

if {[incr ::someUniqueName] > 1} return

The best choice of unique variable name depends on all sorts of factors, but is often a good idea to pick something in your code's namespace; as long as you use the fully-qualified name or ensure the correct namespace context, it will work. (In complex cases, it might make sense to use an array of these things to group that state across multiple files, where the key is [file tail [info script]].)

本文标签: expectWhat is the quotnormalquot way to implement include guards in TCLStack Overflow