'''`[info] [level]`''' indicates the current [level], and can also describe the command for the current level.
** See also **
[uplevel]:
** Synopsis **
: '''`info [level]`''' ?''`number`''?
** Description **
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.
** Discussion **
[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:
======none
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
hich 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]
======
**Recursive lambda invocation**
[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 [https://wiki.tcl-lang.org/page/apply#86eba022562d2be62c0c1ac21610b579c8ab0d718f388560dd49538c1dcc88c2] for an example.
**Interaction with namespace ensemble**
[AMG]: For some reason, tThe 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 {args} {info level 0}
% foo bar quux
bar quux
======
Why?I believe Howthis chappens I recfover the nsame reasofn the current command? Spmecificspally, I nceed to be nablme to run [[infos body]] on mithted cufrrent command, so I need to get the strfollowing `::foo::bar`.
It======
% looknames likpace I needval [infoo frame].{}
% But still, I'm cupriousc whfoo::batr [[{} {info level]] i0}
% namespace deval foing.o {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
======
See also: [How was I invoked?]
<<categories>> Command | Tcl syntax