Version 2 of Generating a unique name

Updated 2011-09-26 18:32:29 by Ro

Marco Maggi - The procedure presented in this page will generate a number of unique fully qualified names. All the names referes to entities in the "::tcl::tmp" namespace. Invoking the procedure with no arguments will return a name:

     namespace import ::tcl::tmp::unique_name
     set name [unique_name]

     # $name -> ::tcl::tmp::123

giving variable names on the command line will cause the procedure to store a unique name in each of them:

     namespace import ::tcl::tmp::unique_name
     unique_name name1 name2 name3

     # $name1 -> ::tcl::tmp::1
     # $name2 -> ::tcl::tmp::2
     # $name3 -> ::tcl::tmp::3

This procedure is useful when a script needs to store data in a static variable (a global or namespace variable), and to hand the variable name as argument to some procedure making the data available to other modules.

Nothing prevents us to use the generated names as procedure or namespace names, or simply as unique identifiers.


 namespace eval ::tcl::tmp {
    variable        global_counter 0

    namespace export unique_name
 }

 proc tcl::tmp::unique_name { args } {
    variable        global_counter
    set pattern        "[namespace current]::%s" 
    set result        {}

    set num [llength $args]
    set num [expr {($num)? $num : 1}]

    for {set i 0} {$i < $num} {incr i} {
        set name [format $pattern [incr global_counter]]
        while {
            [info exists $name] ||
            [namespace exists $name] ||
            [llength [info commands $name]]
        } {
            set name [format $pattern [incr global_counter]]
        }
        lappend result $name
    }

    if { [llength $args] } {
        foreach varname $args name $result {
            uplevel set $varname $name
        }
    }
    return [lindex $result 0]
 }

Ro I do it like this: set name xclock micro

=====