From: ashu on
Hi,

"array names" is unable to retrieve the appropriate keys, that
contains "[]", from the associative array. Please consider the
following example.

I have tried two cases here. In the first case, I use the keys
directly. In the second case, keys have been inserted as a list.
However, in both the cases, I am unable to find out the keys for the
below mentioned pattern.


% set i1 val1
val1
% set i2 {val21/val22[0]}
val21/val22[0]
% set i3 val3
val3
% array set mylist [list]
% set mylist($i1,$i2,$i3) junk_val
junk_val
% array names mylist "$i1,$i2,*"
%
%
% set mylist([list $i1 $i2 $i3]) junk_val
junk_val
% array names mylist [list $i1 $i2 *]
%
%

Thanks,
Ashutosh
From: Alexandre Ferrieux on
On Jun 24, 2:08 pm, ashu <parkhi.ashut...(a)gmail.com> wrote:
> Hi,
>
> "array names" is unable to retrieve the appropriate keys, that
> contains "[]",

Square brackets are a metacharacter of the glob-matching syntax, just
like stars.
Protect them with a backslash when you want to pass them literally as
a second argument of [array get].

-Alex
From: ashu on
Thanks Alex.

The array mentioned in the previous post "mylist" may contain various
types of keys. Some of them may contain "[]", while some may not.
Consequently, at the time of accessing the keys using array names
[pattern]/array get [pattern], I may not know whether the $i2 contains
"[]".

Is there any other way of storing elements like "i2" (containing
metacharacters) in the associative array so that the array names/get
works correctly?
From: Alexandre Ferrieux on
On Jun 24, 3:14 pm, ashu <parkhi.ashut...(a)gmail.com> wrote:
> Thanks Alex.
>
> The array mentioned in the previous post "mylist" may contain various
> types of keys. Some of them may contain "[]", while some may not.
> Consequently, at the time of accessing the keys using array names
> [pattern]/array get [pattern], I may not know whether the $i2 contains
> "[]".
>
> Is there any other way of storing elements like "i2" (containing
> metacharacters) in the associative array so that the array names/get
> works correctly?

All characters are stored properly. What needs special care is the
passing of a variable pattern as 2nd argument to [array get].
The solution is to define a [globprotect] function, and wrap the
literal part of the variable pattern inside it:

proc globprotect s {
regsub -all {[][*?\\]} $s {\\&} s
return $s
}
...
array names mylist "[globprotect $i1,$i2],*"

-Alex
From: Bruce on
ashu wrote:
> Thanks Alex.
>
> The array mentioned in the previous post "mylist" may contain various
> types of keys. Some of them may contain "[]", while some may not.
> Consequently, at the time of accessing the keys using array names
> [pattern]/array get [pattern], I may not know whether the $i2 contains
> "[]".
>
> Is there any other way of storing elements like "i2" (containing
> metacharacters) in the associative array so that the array names/get
> works correctly?

no, but you can preprocess the variables used in the array names call

see bottom of page <http://wiki.tcl.tk/1474>

for this section:

-------------------------------------------------------------------------------
Sarnold: Sometimes glob-like patterns are expected to be passed to some
commands. This may lead to bugs, for example, in [2]:

set bar {x[y]}
set foo($bar) yes
array unset foo $bar
parray foo => foo(x[y]) still exists

What's the cure, Doctor? Unglob it!

proc unglob {x} {
string map {* \\* ? \\? [ \\[ ] \\]} $x
}
-------------------------------------------------------------------------------