有没有办法使用另一个 tcl 文件或在同一个文件中列出 myFile.tcl 中的所有过程(proc)。
问问题
1718 次
4 回答
1
您可以[info procs]
在获取相关文件之前和之后使用并比较结果以确定添加了哪些 proc。例如:
proc diff {before after} {
set result [list]
foreach name $before {
set procs($name) 1
}
foreach name $after {
if { ![info exists procs($name)] } {
lappend result $name
}
}
return [lsort $result]
}
set __before [info procs]
source myFile.tcl
set __after [info procs]
puts "Added procs: [diff $__before $__after]"
我喜欢这个解决方案的一件事是,该diff
过程实际上只是一个通用的集差分实用程序——它并不特定于比较已定义过程的列表。
于 2013-10-18T17:27:45.263 回答
1
最便宜的方法是打开文件并使用regexp
来挑选名称。它并不完全准确,但它做得相当不错。
set f [open "sourcefile.tcl"]
set data [read $f]
close $f
foreach {dummy procName} [regexp -all -inline -line {^[\s:]*proc (\S+)} $data] {
puts "Found procedure $procName"
}
它处理所有情况吗?不。它是否处理有用的子集?是的。子集对您来说足够大吗?很有可能。
于 2013-10-18T23:18:30.273 回答
0
是的,虽然不是那么容易。基本思想是在只执行一些命令的修改过的从 interp 中获取文件:
proc proc_handler {name arguments body} {
puts $name
}
set i [interp create -safe]
interp eval $i {proc unknown args {}}
interp alias $i proc {} proc_handler
interp invokehidden source yourfile.tcl
如果文件需要其他包(package require
不起作用),这种方法将失败,依赖于一些通常 auto_load'ed 命令的结果等。
它也没有考虑命名空间。(namespace eval ::foo {proc bar a {}}
创建一个名称为 proc::foo::bar
对于更复杂的实现,您可以查看auto.tcl的 auto_mkindex,它具有类似的目标。
于 2013-10-18T15:21:30.053 回答
0
这是一种不同的方法:
- 创建临时命名空间
- 源(包括)有问题的脚本,然后
- 使用
info procs
命令获取 procs 列表 - 完成后删除临时命名空间
这是我的脚本,*list_procs.tcl*:
#!/usr/bin/env tclsh
# Script to scan a Tcl script and list all the procs
proc listProcsFromFile {fileName} {
namespace eval TempNamespace {
source $fileName
set procsList [info procs]
}
set result $::TempNamespace::procsList
namespace delete TempNamespace
return $result
}
set fileName [lindex $::argv 0]
set procsList [listProcsFromFile $fileName]
puts "File $fileName contains the following procs: $procsList"
例如,如果您有以下脚本procs.tcl:
proc foo {a b c} {}
proc bar {a} {}
然后运行脚本将产生:
$ tclsh list_procs.tcl procs.tcl
File procs.tcl contains the following procs: foo bar
于 2013-10-18T17:04:12.030 回答