0
votes
proc hello {} {
     puts "hey"
     after 1000 hello
}
proc hello {} {
    global hello
    puts "hey"
    set hello [info level 0]
    after 1000 [namespace code [info level 0]]
}

I just wrote simple program, if adding namespace, global<proc name>, info level... doesn't mean anything extra here, please add your code to explain significance of namespace, global<proc name>, info level... When to use which of these?

1
Did you read the documentation for those commands?Shawn
Yes, i did. But unable to understand much. Will you please explain .Aman Agrawal
One thing that might help is realizing that tcl has different namespaces (Not related to the namespace command) for command names and variable names.Shawn
The use of info 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

1 Answers

1
votes

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)" }