在Tcl文件中列出所有过程的方法
是否有任何方法可以使用另一个tcl文件或同一文件列出myFile.tcl中的所有过程(proc)。是的,尽管不是那么容易。基本思想是在修改的从属interp中生成文件,该从属interp只执行一些命令:在Tcl文件中列出所有过程的方法,tcl,expect,Tcl,Expect,是否有任何方法可以使用另一个tcl文件或同一文件列出myFile.tcl中的所有过程(proc)。是的,尽管不是那么容易。基本思想是在修改的从属interp中生成文件,该从属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 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
将不起作用),依赖于一些通常自动加载的命令等的结果,这种方法将失败
它也不考虑名称空间。(namespace eval::foo{proc bar a{}
创建一个名为::foo::bar
对于更复杂的实现,您可以查看具有类似目标的auto_mkindex。这里有一种不同的方法:
info procs
命令获取过程列表#!/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:
然后运行脚本将生成:
$ tclsh list_procs.tcl procs.tcl
File procs.tcl contains the following procs: foo bar
您可以在查找相关文件之前和之后使用
[info procs]
,并比较结果以确定添加了哪些程序。例如:
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
过程实际上只是一个通用的集合差分实用程序——它并不特定于比较已定义过程的列表。最便宜的方法是打开文件,然后使用regexp
来选择名称。这不是非常准确,但它相当有用d工作
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"
}
它处理所有情况吗?不。它处理有用的子集吗?是的。子集对您来说足够大吗?很可能。您想要进程名称,还是需要查看arg列表和/或进程体?如果您的系统有它,
包需要struct::set
并使用struct::set difference
而不是编写自己的代码ndiff
.Pro:不必编写,可重复使用。缺点:只需使用一个函数,就必须导入大量代码。使用子interp更好。大多数Tcl文件使用全名,因此它们忽略您的命名空间。
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"
}