Reputation: 1141
There is a code which generate the file with one proc:
puts $fh "proc generate \{ fileName\} \{"
puts $fh "[info body generateScriptBody]"
puts $fh "\}"
puts $fh "generate"
close $fh
proc generateScriptBody{} {
source something1
source something2
...
}
In this case should I source
inside proc or there are alternatives?
Upvotes: 0
Views: 1051
Reputation: 1295
I just encountered a problem with calling source inside a proc, maybe it's helpful for someone.
I have two test files. This is sourcetest1.tcl
which sources sourcetest2.tcl
in three different ways:
puts "sourcetest1.tcl"
proc mysource_wrong {script} {
source $script
}
proc mysource_right {script} {
uplevel "source sourcetest2.tcl"
}
#source sourcetest2.tcl
#mysource_right sourcetest2.tcl
mysource_wrong sourcetest2.tcl
This is sourcetest2.tcl
:
puts "sourcetest2.tcl"
set l {1 2 3}
puts "outside: $l"
proc doit {} {
global l
puts "doit: $l"
}
doit
Everything is fine with a direct source
and with mysource_right
, the output is in both cases:
sourcetest1.tcl
sourcetest2.tcl
outside: 1 2 3
doit: 1 2 3
However, with mysource_wrong
, we get the following output:
sourcetest1.tcl
sourcetest2.tcl
outside: 1 2 3
can't read "l": no such variable
while executing
"puts "doit: $l""
(procedure "doit" line 3)
invoked from within
"doit"
(file "sourcetest2.tcl" line 12)
invoked from within
"source $script"
(procedure "mysource_wrong" line 2)
invoked from within
"mysource_wrong sourcetest2.tcl"
(file "sourcetest1.tcl" line 13)
My interpretation is that a source
inside a proc
puts the variable l
into the scope of the proc
, not into the global scope. This can be avoided by using uplevel
like in mysource_right
.
Upvotes: 2
Reputation: 40763
I don't understand what you are trying to do, but source within a proc is acceptable. If you are looking to write the whole proc into a file, take a look at saveprocs
from the TclX package; it will help simplifying your code.
Here is an example of using saveprocs
:
package require Tclx
# Generate a proc from body of one or more files
set body [read_file something1]
append body "\n" [read_file something2]
proc generate {fileName} $body
# Write to file
saveprocs generate.tcl generate
In this case, I did away with all the source
commands and read the contents directly into the proc's body.
Upvotes: 2