proc which_alias {cmd} {
uplevel 1 [list ::trace add execution $cmd enterstep ::error]
catch {uplevel 1 $cmd} res
uplevel 1 [list ::trace remove execution $cmd enterstep ::error]
return $res
}Below some procs to inspect aliases simliar to info args, a similar proc for info body can be built easily (just use the alias following outlined below and apply info body to the actual target of the alias). Note: Since this procedure was written with the (incorrect) assumption that the interp subcommands will accept any variant of a command name as alias token, it doesn't always work.
# [info args] like proc following an alias recursivly until it reaches
# the proc it originates from or cannot determine it.
# accounts for default parameters set by interp alias
#
proc aliasargs {cmd} {
set orig $cmd
set defaultargs [list]
# loop until error or return occurs
while {1} {
# is it a proc already?
if {[string equal [info procs $cmd] $cmd]} {
set result [info args $cmd]
# strip off the interp set default args
return [lrange $result [llength $defaultargs] end]
}
# is it a built in or extension command we can get no args for?
if {![string equal [info commands $cmd] $cmd]} {
error "\"$orig\" isn't a procedure"
}
# catch bogus cmd names
if {[lsearch [interp aliases {}] $cmd]==-1} {
error "\"$orig\" isn't a procedure or alias or command"
}
if {[llength [set cmdargs [interp alias {} $cmd]]]>0} {
# check if it is aliased in from another interpreter
if {[catch {interp target {} $cmd} msg]} {
error "Cannot resolve \"$orig\", alias leads to another interpreter."
}
if {$msg != {} } {
error "Not recursing into slave interpreter \"$msg\".\
\"$orig\" could not be resolved."
}
# check if defaults are set for the alias
if {[llength $cmdargs]>1} {
set cmd [lindex $cmdargs 0]
set defaultargs [concat [lrange $cmdargs 1 end] $defaultargs]
} else {
set cmd $cmdargs
}
}
}
}As it was discussed in the tcl'ers chatroom there are some complex situations that can arise with alias introspection, especially with cross interp aliases.
- info level, especially with a negative level, may not work as expected
- uplevel and upvar may do unexpected things

