f



array names fails to find the pattern if the key contains []

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
0
ashu
6/24/2010 12:08:22 PM
comp.lang.tcl 23428 articles. 2 followers. Post Follow

6 Replies
458 Views

Similar Articles

[PageSpeed] 3

On Jun 24, 2:08=A0pm, ashu <parkhi.ashut...@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
0
Alexandre
6/24/2010 1:03:54 PM
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?
0
ashu
6/24/2010 1:14:47 PM
On Jun 24, 3:14=A0pm, ashu <parkhi.ashut...@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
0
Alexandre
6/24/2010 1:34:21 PM
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
  }
-------------------------------------------------------------------------------
0
Bruce
6/24/2010 1:36:39 PM
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?

You are asking the wrong question ;-)

in
[array names $arr $patt]
or
[array get $arr $patt]

$patt is evaluated as a glob style pattern!

there is no limitation to what can be used for an array key.

try:
proc escape4glob patt {
	set escaped [ string map [list \{ \\\{ \} \\\{ \[ \\\[ \] \\\] * \\*] $patt ]
}
set testpatt [ escape4glob $i1 ],[ escape4glob $i2 ],*

[array get $arr $testpatt]

uwe
0
Uwe
6/24/2010 1:39:43 PM
Thanks to all of you. All the solutions worked for me :)
0
ashu
6/25/2010 4:25:18 AM
Reply: