TCL pretty much treats everything as a string or list. Crafting complex data
structures can be done (put lists of lists together and define some get() set() procedures for working with the data).
What if you don't want to do that?
According to the tcl wiki, the canonical answer looks like the following, using a list as the key for the associative array:
array set commands [list \
[list cisco ping ] "ping %s source %s" \
[list netopia ping ] "ping %s source %s" \
[list siemens ping ] "ping -I %s %s" \
]
That data structure looks workable, however the order of the format arguments matters, and the siemens ping command
has the reverse order of the others. We could create a wrapper function... and remember to call it to format
the command correctly. We can avoid that cognitive load by implementing lambda() in TCL:
# XXX have to always pass in a list
proc lambda {arg body} {
set name [format "%s%s" $arg $body] ; # ensure global uniqueness
proc $name $arg $body
return $name
}
array set commands [list \
[list cisco ping ] [lambda x { format "ping %s source %s" [lindex $x 0] [lindex $x 1] } ] \
[list netopia ping ] [lambda x { format "ping %s source %s" [lindex $x 0] [lindex $x 1] } ] \
[list siemens ping ] [lambda x { format "ping -I %s %s" [lindex $x 1] [lindex $x 0] } ] \
]
puts [$commands([list cisco ping]) [list 1.1.1.1 2.2.2.2] ]
puts [$commands([list netopia ping]) [list 1.1.1.1 2.2.2.2] ]
puts [$commands([list siemens ping]) [list 1.1.1.1 2.2.2.2] ]
Yielding the following ...
ping 1.1.1.1 source 2.2.2.2
ping 1.1.1.1 source 2.2.2.2
ping -I 2.2.2.2 1.1.1.1
Now to fill out a whole lot more commands.... ;)