On 8/2/13 1:24 PM, Roland Mainz wrote:
> On Fri, Aug 2, 2013 at 8:12 PM, Terrence J. Doyle
> <[email protected]> wrote:
>>
>>         That explains the format change. While this seems a bit inconsistent
>> with the output of ${!array[@]}, I'm not going to quibble about format.
>>
>>         However, my comments concerned the reporting of nonexistent
>> indexes/keys. What's the purpose of the construct if it reports an array
>> index/key where none exists? To put it another way, before the change
>> the test:
>>
>>         [[ ${!array[$index]} ]]
>>
>> was useful. Now, it's meaningless since it's always true -- even if
>> $index isn't an index of the array.
> 
> Erm... do you want to figire out whether an element in array is set or
> not ? ksh93 has the [[ -v ... ]] operator for that, e.g. typeset -a
> ar=( 2 3 4 ) ; [[ -v ar[1] ]] && print 'ok1' ; [[ -v ar[9] ]] && print
> 'ok9'
> 
> will print 'ok1'
> 
> Note that this uses the variable names and not the value to test...
> which is vastly faster than trying to test the value.

        Well, in going through the release notes it appears that the -v test
operator for array elements is quite new:

09-01-26 +The [[ -v var ]] operator was modified to test for array elements.

In fact, it even postdates the change we're discussing:

07-09-18  The value of ${!var[sub]} was not expanding to var[sub] and this
          was fixed.  It also fixed ${name} where name is a name reference
          to var[sub].

In dusting off some of my old (older than -v) scripts, it appears that I
was sometimes using [[ ${!array[$index]} ]] for the utility and
performance (or so I assumed) that the -v test operator now provides.
Performance aside, I used this to emphasize (particularly with
associative arrays) that I was more interested in the array subscript
than the value at that location in the array.

        And with that I ask again, what's the purpose of ${!array[$index]}
since the change? It's no longer a natural artifact of ${!array[@]} and
${!array[*]} since its function and output format are no longer
consistent with them.

        But wait. I'm beginning to see the answer to my question. From what
I've been able to glean from this is that the change was made to support
reflection. Thus, one can now do the following:

        $ array[1]=a
        $ eval print \${$!array[1]}}
        a
        $

The change also recursively supports ${!ref}, where ref is a name
reference to array[index]. So, by itself ${!array[index]} (or
${!var[sub]} as it's presented in the documentation) really isn't very
useful. It exists simply to support reflection and name references. I
respectfully suggest that the documentation be updated to make this clear.

        What about ${!array[@]} and ${!array[*]}? Shouldn't they also support
reflection the same way? Thus:

        $ typeset -A assoc=(
        > [just]='a simple demo:'
        > [suggesting]='reflection of @ array expansion'
        > )
        $ print ${!assoc[@]}
        assoc[just] assoc[suggesting]
        $ for reflection in ${!assoc[@]}
        > do
        >       eval print \"\${$reflection}\"
        > done
        a simple demo:
        reflection of @ array expansion
        $

At the very least this restores the output format consistency between
${!var[sub]} and its ${!var[@]} and ${!var[*]} counterparts.

                                        Terrence Doyle

PS:

        While investigating this I stumbled across what definitely is a bug
with name references. But, it's mostly separate from this thread, so
I'll report it in a separate message with a new subject.
_______________________________________________
ast-users mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to