Reputation: 1
I am trying to write a wrapper tcl which sources multiple tcl files and these tcl files have some proc which have the same names in more than 1 file. How do I explicitly call for a proc from a particular file?
I searched stack overflow and I came across proc rename, but I am wondering if there is another solution. Perhaps cleaner.
Upvotes: 0
Views: 612
Reputation: 3434
You can organise the source
'ed procs in separate namespaces, e.g., by re-using the script names as namespace names:
namespace eval ::[file tail [info script]] {
proc calculate {a b} {
return [expr {$a+$b}]
}
namespace export calculate
}
namespace eval ::[file tail [info script]] {
proc calculate {a b} {
return [expr {$a-$b}]
}
namespace export calculate
}
Then, in your main script, you may switch back and forth between the different proc pools e.g. using [namespace import]
:
% source add.tcl
% source sub.tcl
% namespace import -force ::add.tcl::*
% calculate 5 3
8
% namespace import -force ::sub.tcl::*
% calculate 5 3
2
[info script]
returns the currently sourced script file (is set by the source
command behind the scenes).[namespace export]
the pooled procs. Otherwise, they won't become imported.-force
flag on namespace import
will silently replace equally named commands (procs) in the target namespace.source
context? etc.source
that avoids the boilerplate in each and every source
'ed script.Upvotes: 1
Reputation: 16438
It is kind of tricky, but you can go ahead with slave interpreters to distinguish between the files.
add.tcl
proc calculate {a b} {
return [expr {$a+$b}]
}
sub.tcl
proc calculate {a b} {
return [expr {$a-$b}]
}
file_src_manager.tcl
array set tclEngine {}
set files {add.tcl sub.tcl}
foreach f $files {
# Creating slave interpreter for each files.
set tclEngine($f) [interp create]
# Sourcing them in separate interpreter
if {[catch {interp eval $tclEngine($f) "source $f"} issue]} {
puts "Failed to source $f. Reason - $issue"
}
}
# Calling add.tcl file's calculate method
puts [interp eval $tclEngine(add.tcl) "calculate 5 3"]
# Calling sub.tcl file's calculate method
puts [interp eval $tclEngine(sub.tcl) "calculate 5 3"]
Output
8
2
Reference : interp
Upvotes: 1