[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 `x[[[clock] micro]]` ---- [PYK] 2016-01-20: Here's a snippet that produces a string of random letters, 24 in this case: ====== proc uniqid {} "lindex [string repeat {[format %c [expr {entier(rand() * 26 + (int(rand()*10 > 4 ? 97 : 65)))}]]} 24]" ====== And here is one that produces an a string of printable characters that, when interpreted as a base-68 number occupies approximately, but no more than 256 bits: ====== proc uniqid {} "lindex [string repeat {[lindex {# % + - ^ = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z} [expr {entier(rand() * 68)}]]} 42]" ====== A version of `uniqid`, called `printuniq_256`, that uses `/dev/random` is available in `[ycl] math rand`. Another command, `printuniq_script` accepts a random number generator and a count, and generates a script similar to `uniqid`. <> Uncategorized