I assume you already understand what the first one does, and why? And that I don't need to cover what global
does?
The command info level 0
reports the exact arguments including the command name used to invoke the command. By putting this in a namespace code
you create a script that can be called from anywhere and will behave as if it was run in the current namespace, which is rather useful in quite a few cases. (The script also does some trickery with argument concatenation which isn't needed here, but which helps a lot when setting up traces and other sorts of concatenative out-of-context callback; the result of namespace code
is always a proper list that acts as a command invocation prefix.)
It's massively overkill to use these for this example! It gets a lot more clear when we add in some arguments:
namespace eval say {
proc hello1 {person} {
puts "hey $person"
# Note that we have to do additional work here
after 1000 [list ::say::hello1 $person]
}
proc hello2 {person} {
global hello
puts "hey $person"
set hello [info level 0]
# Note that the code here didn't change!
after 1000 [namespace code [info level 0]]
}
}
say::hello1 "Aman Agrawal (from #1)"
say::hello2 "Aman Agrawal (from #2)"
# Be sure to also try:
# namespace eval say { hello2 "Aman Agrawal (from #2, call style 2)" }
namespace
command) for command names and variable names. – Shawninfo level 0
is… making this code probably far more complicated than it ever needs to be for saying hello every second. The value of the second one really comes in once you start passing non-trivial arguments around and putting the code in namespaces other than the global one. – Donal Fellows