info level indicates the current level, and can also describe the command for the current level.
If number is specified, info levels returns a list consisting of words of the command for the level indicated by number. A number greater than 0 indicates the level identified by that number. 0 indicates the current level, -1 indicates one level prior to the current level, -2 indicates the level prior to that one, and so on.
If number is not specified, info level returns a number indicating the current level, i.e. the level from which info level was called. 0 is top level, and each subsequent level is incremented by 1.
MGS 2003-09-09: info level 0 does not return values for optional arguments (if they have not been specified):
proc foo {bar {baz NULL}} { puts "info level 0 = \[[info level 0]\]" } # example1 foo abc def # example2 foo abc
prints:
info level 0 = [foo abc def] info level 0 = [foo abc]
DGP Correct. info level $level returns the substituted list of values that make up the actual command as evaluated.
To get values for non-specified default arguments, you have to do quite a bit more work using info args and info default.
This proc will print out info for all args in the calling proc (note: does not handle being called from global level).
proc arginfo {} { set proc [lindex [info level -1] 0] set which [uplevel [list namespace which -command $proc]] puts "proc \[$which\]" set i -1 foreach arg [info args $which] { incr i set value [uplevel [list set $arg]] if { [info default $which $arg def] } { puts " arg\[$i\] \[$arg\] = \[$value\] default = \[$def\]" } else { puts " arg\[$i\] \[$arg\] = \[$value\]" } } } # test code proc test {foo {"bar baz" "BAR BAZ"}} { arginfo } test abc test abc def
which prints the output:
proc [::test] arg[0] [foo] = [abc] arg[1] [bar baz] = [BAR BAZ] default = [BAR BAZ] proc [::test] arg[0] [foo] = [abc] arg[1] [bar baz] = [def] default = [BAR BAZ]
AMG: [info level 0] is useful for writing a lambda (anonymous procedure invoked using apply) that can recursively call itself despite not having a name. See [L1 ] for an example.
AMG: The name of the namespace ensemble does not appear in the return value of [info level 0].
% namespace eval foo { namespace export * namespace ensemble create } % proc foo::bar {} {info level 0} % foo bar bar
I believe this happens for the same reason the namespace name is omitted from the following:
% namespace eval foo {} % proc foo::bar {} {info level 0} % namespace eval foo {bar} bar
To recover the full name of the current command, use namespace origin:
% namespace eval foo { namespace export * namespace ensemble create } % proc foo::bar {args} { namespace origin [lindex [info level 0] 0] } % foo bar ::foo::bar % namespace eval foo {bar} ::foo::bar
PYK 2022-03-24: In the script above namespace which would be better than namespace origin because the intent to fully qualify the nam of the procedure, not to trace an imported name back to its origin. Of course, sometimes namespace origin is exactly what is desired. It's just not a synonym for namespace which.
See also: How was I invoked?