zsh-users
 help / color / mirror / code / Atom feed
* easy calling of associative array?
@ 2015-11-01 23:12 Ray Andrews
  2015-11-01 23:55 ` ZyX
  0 siblings, 1 reply; 20+ messages in thread
From: Ray Andrews @ 2015-11-01 23:12 UTC (permalink / raw)
  To: Zsh Users


test ()
{
     eval "baz=\$${1}[key1]"
     echo $baz
eval "foo=\$${1}[key2]"
     echo $foo
...
}

If I want to pass the name of an associative array to a function via 
"$1" and then work with it's keys, the above succeeds but it's sure 
laborious. Is there some way to do the eval just once?  So that I can 
end up doing:

if [ "xyz[key1]" = '1' ]; then ...

... as I experiment, there seems to be no way of replacing 'xyz' with 
any expression that will do the job without needing eval's help every 
time, but I'll bet there's a way.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-01 23:12 easy calling of associative array? Ray Andrews
@ 2015-11-01 23:55 ` ZyX
  2015-11-02  0:49   ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: ZyX @ 2015-11-01 23:55 UTC (permalink / raw)
  To: Ray Andrews, Zsh Users


02.11.2015, 02:44, "Ray Andrews" <rayandrews@eastlink.ca>:
> test ()
> {
>      eval "baz=\$${1}[key1]"
>      echo $baz
> eval "foo=\$${1}[key2]"
>      echo $foo
> ...
> }
>
> If I want to pass the name of an associative array to a function via
> "$1" and then work with it's keys, the above succeeds but it's sure
> laborious. Is there some way to do the eval just once? So that I can
> end up doing:
>
> if [ "xyz[key1]" = '1' ]; then ...
>
> ... as I experiment, there seems to be no way of replacing 'xyz' with
> any expression that will do the job without needing eval's help every
> time, but I'll bet there's a way.

There is ${(P)} for indirect referencing:

    % foo=path
    % echo ${${(P)foo}[1]} $path[1]
    /home/zyx/.local/bin /home/zyx/.local/bin

. This is in `man zshexpn`.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-01 23:55 ` ZyX
@ 2015-11-02  0:49   ` Ray Andrews
  2015-11-02  3:08     ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Ray Andrews @ 2015-11-02  0:49 UTC (permalink / raw)
  To: zsh-users

On 11/01/2015 03:55 PM, ZyX wrote:
> 02.11.2015, 02:44, "Ray Andrews" <rayandrews@eastlink.ca>:
>
> There is ${(P)} for indirect referencing:
>
>      % foo=path
>      % echo ${${(P)foo}[1]} $path[1]
>      /home/zyx/.local/bin /home/zyx/.local/bin
>
> . This is in `man zshexpn`.
>
I can't get it to work with associative arrays tho.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02  0:49   ` Ray Andrews
@ 2015-11-02  3:08     ` Bart Schaefer
  2015-11-02  3:33       ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-02  3:08 UTC (permalink / raw)
  To: zsh-users

On Nov 1,  4:49pm, Ray Andrews wrote:
} Subject: Re: easy calling of associative array?
}
} On 11/01/2015 03:55 PM, ZyX wrote:
} >
} > There is ${(P)} for indirect referencing:
}
} I can't get it to work with associative arrays tho.

Yeah, it's a bit weird with associative arrays because everything is
passed by value.  ${(P)ref} is ${(vP)ref} and thus ${${(P)ref}[idx]}
doesn't get what you want, and ${(P)ref[idx]} is ${(P)${ref[idx]}}
which also isn't what you want.

So you have to get a little arcane:  ${(P)${:-${ref}[idx]}}.

- ${ref} is the name of the assocative array.

- ${ref}[idx] is therefore a string that has the same format as the
  array lookup you want to perform.

- ${:-${ref}[idx]} substitutes that string into a parameter expansion.

- ${(P)${:-${ref}[idx]}} then treats that substitution as another
  parameter expansion, and you end up where you wanted to be.

This is admittedly not ideal, but until we embark on a significant
rewrite of parameter expansion, we're stuck maneuvering values into
the right places at the right times.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02  3:08     ` Bart Schaefer
@ 2015-11-02  3:33       ` Ray Andrews
  2015-11-02  6:51         ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Ray Andrews @ 2015-11-02  3:33 UTC (permalink / raw)
  To: zsh-users

On 11/01/2015 07:08 PM, Bart Schaefer wrote:
> - ${(P)${:-${ref}[idx]}} then treats that substitution as another
>    parameter expansion, and you end up where you wanted to be.
Deus avertat.  But what would prevent this from being parsed?:

${${ref}[idx]}

or even:

${${ref}[$idx]}

... since an expansion can be used in the back end just fine already.
I dunno, but the above seems at least naively straight forward.
Also, that form  works with normal arrays. But if you say it
can't work that way I can't say otherwise, of course.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02  3:33       ` Ray Andrews
@ 2015-11-02  6:51         ` Bart Schaefer
  2015-11-02 15:43           ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-02  6:51 UTC (permalink / raw)
  To: zsh-users

On Nov 1,  7:33pm, Ray Andrews wrote:
}
} But what would prevent this from being parsed?:
} 
} ${${ref}[idx]}
} ${${ref}[$idx]}

Those both ARE parsed.  The problem is, that form is defined to mean
something different than what it would have to mean for it to work
in (P) context.  It's not a parsing issue.

} Also, that form  works with normal arrays.

Presuming you mean ${${(P)ref}[idx]}, because it means something else
if you leave out the (P) or put it somewhere else.

Anyway, that's actually the point.  ${(P)ref} resolves to the values of
the array, and then the subscript is applied.  Ask yourself: what are
"the values of" an associative array, in every other context?


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02  6:51         ` Bart Schaefer
@ 2015-11-02 15:43           ` Ray Andrews
  2015-11-02 16:28             ` Bart Schaefer
  2015-11-02 19:33             ` ZyX
  0 siblings, 2 replies; 20+ messages in thread
From: Ray Andrews @ 2015-11-02 15:43 UTC (permalink / raw)
  To: zsh-users

On 11/01/2015 10:51 PM, Bart Schaefer wrote:
> Anyway, that's actually the point.  ${(P)ref} resolves to the values of
> the array, and then the subscript is applied.  Ask yourself: what are
> "the values of" an associative array, in every other context?
I'll give it some time, this is new to me.  It seems that with an 
associative array,
what we have is some 'hidden' syntax, IOW there is a sort of shorthand going
on.  As with math, I'd sorta expect that if this functionality was 
tacked on
after the fundamentals of the shell were already in place--you leveraged
what was there--there'd be asymmetries.

Experimenting with trying to make accessing associative arrays convenient:

    echo_v ()
    {
    echo ${(P)${:-${1}[$2]}}    #this works
    #eval "echo \$${1}[$2]"     #and this works too.
    }

    get_v ()
    {
    #$3=${(P)${:-${1}[$2]}}     #nothing works
    eval "$3=\$${1}[$2]"        #this works
    }

    set_v ()
    {
    # {(P)${:-${1}[$2]}}=$3       #nothing works
    eval "${1}[$2]=$3"            #this works
    }

    test_v ()
    {
    #eval "${1}[$2]"            #nothing works
                                 #this works
    [ ${(P)${:-${1}[$2]}} = $3 ] && echo 'all too true' || echo 'alas, no.'
    }


I notice that with 'echo_v' I can use your syntax or 'eval' the thing 
which is
much easier to read if nothing else.  But with 'get_v' and 'set_v' I can 
only make
it work with 'eval' whereas with 'test_v' I can *not* make it work with 
'eval'.
At the risk of being too much of a symmetry nut, is it possible to make 
either
form work in all the above situations?  If so, I have a consistent 
interface to
these arrays which would be pleasing, but it's an academic point.

FWIW, this is in the context of studying Sebastian's stuff--there's all 
these
variables sloshing about for each of several zcurses windows, and it 
would be
C-ish to organize them into arrays, one for each window.  However I can
see that this is at the limits of what a shell should be asked to do, since
what I really want is a proper C structure for data:

main_window.window_height

becomes:

${main_window[window_height]}

... but of course I want to be able to replace 'main_window' with
any other window via a variable passed to whatever function:

whatever_window->window_height

becomes:

${(P)${:-${whatever_window}[window_height]}}

... which looks like it's going to work just so long as I can perform 
any sort
of operation on the array without difficulty. But there could be speed 
issues
and the whole thing might not be worth the trouble, but it is educational
at least.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 15:43           ` Ray Andrews
@ 2015-11-02 16:28             ` Bart Schaefer
  2015-11-02 18:32               ` Ray Andrews
  2015-11-02 19:33             ` ZyX
  1 sibling, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-02 16:28 UTC (permalink / raw)
  To: zsh-users

On Nov 2,  7:43am, Ray Andrews wrote:
}
}     get_v ()
}     {
}     #$3=${(P)${:-${1}[$2]}}     #nothing works
}     eval "$3=\$${1}[$2]"        #this works
}     }

This has nothing to do with associative arrays and everything to do with
assignment syntax.  "$3" is not a valid identifier, so "$3=" is not an
assignment; this all decided before $3 is expanded, which is why putting
the "eval" around it works (it delays the "is an identifier" check until
after $3 has expanded).

Probably the most cogent way to do this is

    get_v () {
      typeset -g $3="${(P)${:-${1}[$2]}}"
    }

}     set_v ()
}     {
}     # {(P)${:-${1}[$2]}}=$3       #nothing works
}     eval "${1}[$2]=$3"            #this works
}     }

Same assignment-syntax problem.

    set_v () {
      # typeset -gA $1		# optional
      typeset -g "${1}[$2]=$3"	# quotes so [ ] isn't globbing
    }

Here you don't need the (P) indirection because ${1} and $2 are both
expanded before being passed to typeset, so you already extracted the
name that was passed in $1.

Also note I'm ignoring all possible error checking, e.g. if $1 is not
an identifier (in the worst case, contains an "="), things go badly.

}     test_v ()
}     {
}     #eval "${1}[$2]"            #nothing works
}                                  #this works
}     [ ${(P)${:-${1}[$2]}} = $3 ] && echo 'all too true' || echo 'alas, no.'
}     }

I'm not exactly sure what you're wanting as either output or exit
status here, but except that I'd recommend [[ ]] instead of [ ] as
the test syntax, what you wrote for "this works" is sensible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 16:28             ` Bart Schaefer
@ 2015-11-02 18:32               ` Ray Andrews
  2015-11-02 19:37                 ` ZyX
  2015-11-02 21:05                 ` Bart Schaefer
  0 siblings, 2 replies; 20+ messages in thread
From: Ray Andrews @ 2015-11-02 18:32 UTC (permalink / raw)
  To: zsh-users

On 11/02/2015 08:28 AM, Bart Schaefer wrote:
> }     #$3=${(P)${:-${1}[$2]}}     #nothing works

Pardon, that was an obvious mistake.  Too much thrashing around with 'eval'.
> Same assignment-syntax problem.
>
>      set_v () {
>        typeset -g "${1}[$2]=$3"	# quotes so [ ] isn't globbing
>      }
>
> Here you don't need the (P) indirection because ${1} and $2 are both
> expanded before being passed to typeset, so you already extracted the
> name that was passed in $1.

... and that's nicely readable too--the sort of syntax that seems 
intuitive, as I
mentioned.  I won't say this is all clear in my mind, but it's
at least tractable. One further question:  I've never seen 'typeset' 
used to refer
to anything but a simple variable.  I note that the above does not work 
without
the 'typeset -g' so what does that accomplish?   I've never thought of the
positional parameters and being typeset-able.  I get the feeling it is a 
future
problem solver.
>
> Also note I'm ignoring all possible error checking, e.g. if $1 is not
> an identifier (in the worst case, contains an "="), things go badly.

Sure, it's naive at this point.  I don't yet think past that.
> I'm not exactly sure what you're wanting as either output or exit
> status here, but except that I'd recommend [[ ]] instead of [ ] as
> the test syntax, what you wrote for "this works" is sensible.

Ok.  I don't pay enough attention to the difference.

BTW, as a point of list etiquette:  Responding to most posts I let my 
lines wrap
but resonding to yours, which seem to alway have fixed line width, I try to
match that style, but looking at the returned posts from the list, they 
sometimes
sproing badly. Should I  try to keep to your width, or just let lines wrap?
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 15:43           ` Ray Andrews
  2015-11-02 16:28             ` Bart Schaefer
@ 2015-11-02 19:33             ` ZyX
  2015-11-02 23:04               ` Ray Andrews
  1 sibling, 1 reply; 20+ messages in thread
From: ZyX @ 2015-11-02 19:33 UTC (permalink / raw)
  To: Ray Andrews, zsh-users



02.11.2015, 18:45, "Ray Andrews" <rayandrews@eastlink.ca>:
> On 11/01/2015 10:51 PM, Bart Schaefer wrote:
>>  Anyway, that's actually the point. ${(P)ref} resolves to the values of
>>  the array, and then the subscript is applied. Ask yourself: what are
>>  "the values of" an associative array, in every other context?
>
> I'll give it some time, this is new to me. It seems that with an
> associative array,
> what we have is some 'hidden' syntax, IOW there is a sort of shorthand going
> on. As with math, I'd sorta expect that if this functionality was
> tacked on
> after the fundamentals of the shell were already in place--you leveraged
> what was there--there'd be asymmetries.
>
> Experimenting with trying to make accessing associative arrays convenient:
>
>     echo_v ()
>     {
>     echo ${(P)${:-${1}[$2]}} #this works

    typeset -A foo
    foo=('abc]def' true)
    echo_v foo 'abc]def'
    # Echoes nothing in place of `true`.

. But `key='abc]def' ; echo $foo[$key]` works.

>     #eval "echo \$${1}[$2]" #and this works too.

Thus you need to eval in the following form:

    eval 'echo $'$1'[$2]'

. Without eval I have only came up with

    echo_v()
    {
        emulate -L zsh
        local -A array
        array=( ${(kvP)1} )
        echo $array[$2]
    }

>     }
>
>     get_v ()
>     {
>     #$3=${(P)${:-${1}[$2]}} #nothing works
>     eval "$3=\$${1}[$2]" #this works

Like previous function, but last line should be

        : ${(P)3::=$array[$2]}

in place of `echo $array[$2]`.

With eval you need to use

    eval $3'=$'$1'[$2]'

>     }
>
>     set_v ()
>     {
>     # {(P)${:-${1}[$2]}}=$3 #nothing works
>     eval "${1}[$2]=$3" #this works
>     }

    set_v()
    {
        emulate -L zsh
        local -A array
        array=( ${(kvP)1} $2 $3 )
        : ${(AAP)1::=${(kv)array}}
    }

Note that all my variants without eval are copying array around, eval variants do not.

Eval here:

    eval $1'[$2]=$3'

.

>
>     test_v ()
>     {
>     #eval "${1}[$2]" #nothing works
>                                  #this works
>     [ ${(P)${:-${1}[$2]}} = $3 ] && echo 'all too true' || echo 'alas, no.'

Pretty much obvious after `echo_v`. Note the same problem with 2='abc]def'

>     }
>
> I notice that with 'echo_v' I can use your syntax or 'eval' the thing
> which is
> much easier to read if nothing else. But with 'get_v' and 'set_v' I can
> only make
> it work with 'eval' whereas with 'test_v' I can *not* make it work with
> 'eval'.
> At the risk of being too much of a symmetry nut, is it possible to make
> either
> form work in all the above situations? If so, I have a consistent
> interface to
> these arrays which would be pleasing, but it's an academic point.

Not purely academic. With eval you automatically run in escaping problems (though rather easy to resolve in this case). Without eval you make your code rather unreadable.

>
> FWIW, this is in the context of studying Sebastian's stuff--there's all
> these
> variables sloshing about for each of several zcurses windows, and it
> would be
> C-ish to organize them into arrays, one for each window. However I can
> see that this is at the limits of what a shell should be asked to do, since
> what I really want is a proper C structure for data:
>
> main_window.window_height
>
> becomes:
>
> ${main_window[window_height]}
>
> ... but of course I want to be able to replace 'main_window' with
> any other window via a variable passed to whatever function:
>
> whatever_window->window_height
>
> becomes:
>
> ${(P)${:-${whatever_window}[window_height]}}
>
> ... which looks like it's going to work just so long as I can perform
> any sort
> of operation on the array without difficulty. But there could be speed
> issues
> and the whole thing might not be worth the trouble, but it is educational
> at least.

You can also always use zpython:

echo_v() zpython 'print(zsh.getvalue(zsh.getvalue("1")[0])[zsh.getvalue("2")[0]])'
get_v()  zpython 'zsh.setvalue(zsh.getvalue("3")[0], zsh.getvalue(zsh.getvalue("1")[0])[zsh.getvalue("2")[0]])'
set_v()  zpython 'ret = zsh.getvalue(zsh.getvalue("1")[0]); ret[zsh.getvalue("2")[0]]=zsh.getvalue("3")[0]; zsh.setvalue(zsh.getvalue("1")[0], ret)'

. Pretty much consistent (except that I have no idea why it thinks that all $N parameters are array parameters, but this is consistent with ${(t)1} which returns “array-special”). But again each function is copying parameters around.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 18:32               ` Ray Andrews
@ 2015-11-02 19:37                 ` ZyX
  2015-11-02 22:10                   ` Bart Schaefer
  2015-11-02 21:05                 ` Bart Schaefer
  1 sibling, 1 reply; 20+ messages in thread
From: ZyX @ 2015-11-02 19:37 UTC (permalink / raw)
  To: Ray Andrews, zsh-users


02.11.2015, 22:03, "Ray Andrews" <rayandrews@eastlink.ca>:
> On 11/02/2015 08:28 AM, Bart Schaefer wrote:
>>  } #$3=${(P)${:-${1}[$2]}} #nothing works
>
> Pardon, that was an obvious mistake. Too much thrashing around with 'eval'.
>>  Same assignment-syntax problem.
>>
>>       set_v () {
>>         typeset -g "${1}[$2]=$3" # quotes so [ ] isn't globbing
>>       }
>>
>>  Here you don't need the (P) indirection because ${1} and $2 are both
>>  expanded before being passed to typeset, so you already extracted the
>>  name that was passed in $1.
>
> ... and that's nicely readable too--the sort of syntax that seems
> intuitive, as I
> mentioned. I won't say this is all clear in my mind, but it's
> at least tractable. One further question: I've never seen 'typeset'
> used to refer
> to anything but a simple variable. I note that the above does not work
> without
> the 'typeset -g' so what does that accomplish? I've never thought of the
> positional parameters and being typeset-able. I get the feeling it is a
> future
> problem solver.

Typeset variant has unresolved problems with `$2` escaping. Writing `${(q)2}` works here, but I have no idea why it works.

Note: when trying to use any of the functions, try with keys `abc]def` and `abc  def` (two spaces inside). First collects most of the errors.

>>  Also note I'm ignoring all possible error checking, e.g. if $1 is not
>>  an identifier (in the worst case, contains an "="), things go badly.
>
> Sure, it's naive at this point. I don't yet think past that.
>>  I'm not exactly sure what you're wanting as either output or exit
>>  status here, but except that I'd recommend [[ ]] instead of [ ] as
>>  the test syntax, what you wrote for "this works" is sensible.
>
> Ok. I don't pay enough attention to the difference.
>
> BTW, as a point of list etiquette: Responding to most posts I let my
> lines wrap
> but resonding to yours, which seem to alway have fixed line width, I try to
> match that style, but looking at the returned posts from the list, they
> sometimes
> sproing badly. Should I try to keep to your width, or just let lines wrap?
>>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 18:32               ` Ray Andrews
  2015-11-02 19:37                 ` ZyX
@ 2015-11-02 21:05                 ` Bart Schaefer
  2015-11-02 23:01                   ` Ray Andrews
  1 sibling, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-02 21:05 UTC (permalink / raw)
  To: zsh-users

On Nov 2, 10:32am, Ray Andrews wrote:
} Subject: Re: easy calling of associative array?
}
} On 11/02/2015 08:28 AM, Bart Schaefer wrote:
} >
} >      set_v () {
} >        typeset -g "${1}[$2]=$3"	# quotes so [ ] isn't globbing
} >      }
} 
} I've never seen 'typeset' used to refer to anything but a simple
} variable.

In the above,

    set_v ary idx val

is going to invoke

    typeset -g ary[idx]=val

because $1 $2 $3 are all expanded after parsing and before calling the
typeset command.  (Zyx has pointed out the lack of robustness.)  Note
that it is not affecting any positional parameters, they're all long
gone (replace by their values) before typeset begins.

} I note that the above does not work without the 'typeset -g' so what
} does that accomplish?

Ordinarly "typeset" inside a function body behaves like "local".  The
-g option tells it not to do that, so that the name "ary" is taken to
come from the calling context instead of the current function context.

} BTW, as a point of list etiquette:  Responding to most posts I let my 
} lines wrap
} but resonding to yours, which seem to alway have fixed line width, I try to
} match that style, but looking at the returned posts from the list, they 
} sometimes
} sproing badly. Should I  try to keep to your width, or just let lines wrap?

The above is what your text would look like if I didn't run it through
a reformatter.  It Used To Be that everyone assumed text should be
folded to be readable on an 80-column display, which, as a guy still
using the email program I wrote myself 20 years ago, I still do.  Then
along came HTML format email, and everybody assumed text should never be
wrapped at all (let the reader's UI deal with it).  Except there's still
this pesky thing about mailing lists preferring plain text, so we end up
with a hypbrid where text as you write it is folded to be readable at
whatever your display width is set, but then it gets re-folded to 80
when you send it -- except that it also keeps any real newlines you
entered, so if you were actually trying to make it look nice, it ends
up like the above instead.

Exactly what you SHOULD do depends on what you're using to write your
email.  In Thunderbird you should probably put literal line breaks only
at the ends of paragraphs, and let it wrap other stuff as it wills.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 19:37                 ` ZyX
@ 2015-11-02 22:10                   ` Bart Schaefer
  2015-11-02 22:50                     ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-02 22:10 UTC (permalink / raw)
  To: zsh-users

These should be robust for Zyx's failure cases (and throw errors in some
other strange cases where they should).  In older zsh where the (b) flag
is not present, (q) will work in MOST cases.

  echo_v () {
    [[ -n $1 ]] && (( ${(P)+1} )) &&
    print -R "${(P)${:-${1}[${(b)2}]}}"
  }

  get_v () {
    [[ -n $1 && $3 != *=* ]] && (( ${(P)+1} )) &&
    typeset -g "${3:-REPLY}=${(P)${:-${1}[${(b)2}]}}"
  }

  set_v () {
    [[ -n $1 ]] && (( ${(P)+1} )) &&
    typeset -g "${1}[${(b)2}]=$3"
  }

  test_v () {
    [[ -n $1 ]] && (( ${(P)+1} )) &&
    [[ ${(P)${:-${1}[${(b)2}]}} = $3 ]]
  }


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 22:10                   ` Bart Schaefer
@ 2015-11-02 22:50                     ` Ray Andrews
  0 siblings, 0 replies; 20+ messages in thread
From: Ray Andrews @ 2015-11-02 22:50 UTC (permalink / raw)
  To: zsh-users

On 11/02/2015 02:10 PM, Bart Schaefer wrote:
>    echo_v () {
>      [[ -n $1 ]] && (( ${(P)+1} )) &&
>      print -R "${(P)${:-${1}[${(b)2}]}}"
>    }
>
>    get_v () {
>      [[ -n $1 && $3 != *=* ]] && (( ${(P)+1} )) &&
>      typeset -g "${3:-REPLY}=${(P)${:-${1}[${(b)2}]}}"
>    }
>
As Peter once observed, there are no obfuscated code contests in zsh ;-)


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 21:05                 ` Bart Schaefer
@ 2015-11-02 23:01                   ` Ray Andrews
  2015-11-03 15:57                     ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Ray Andrews @ 2015-11-02 23:01 UTC (permalink / raw)
  To: zsh-users

On 11/02/2015 01:05 PM, Bart Schaefer wrote:
> } >        typeset -g "${1}[$2]=$3"	# quotes so [ ] isn't globbing

> In the above,
>
>      set_v ary idx val
>
> is going to invoke
>
>      typeset -g ary[idx]=val
>
> Ordinarly "typeset" inside a function body behaves like "local".  The
> -g option tells it not to do that, so that the name "ary" is taken to
> come from the calling context instead of the current function context.

I don't understand. The idea of context here is new to me.  Why is 'ary' 
not a variable
like any other?
> } BTW, as a point of list etiquette:  Responding to most posts I let my
> } lines wrap
> } but resonding to yours, which seem to alway have fixed line width, I try to
> } match that style, but looking at the returned posts from the list, they
> } sometimes
> } sproing badly. Should I  try to keep to your width, or just let lines wrap?
>
> The above is what your text would look like if I didn't run it through
> a reformatter.  It Used To Be that everyone assumed text should be
> folded to be readable on an 80-column display, which, as a guy still
> using the email program I wrote myself 20 years ago, I still do.  Then
> along came HTML format email, and everybody assumed text should never be
> wrapped at all (let the reader's UI deal with it).  Except there's still
> this pesky thing about mailing lists preferring plain text, so we end up
> with a hypbrid where text as you write it is folded to be readable at
> whatever your display width is set, but then it gets re-folded to 80
> when you send it -- except that it also keeps any real newlines you
> entered, so if you were actually trying to make it look nice, it ends
> up like the above instead.

Yes.  Very unfortunate.
>
> Exactly what you SHOULD do depends on what you're using to write your
> email.  In Thunderbird you should probably put literal line breaks only
> at the ends of paragraphs, and let it wrap other stuff as it wills.

Ok.  Gotta get a better program, I hate Tbird.
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 19:33             ` ZyX
@ 2015-11-02 23:04               ` Ray Andrews
  0 siblings, 0 replies; 20+ messages in thread
From: Ray Andrews @ 2015-11-02 23:04 UTC (permalink / raw)
  To: zsh-users

On 11/02/2015 11:33 AM, ZyX wrote:


Thanks for at that ZyX, it will take a while to digest.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-02 23:01                   ` Ray Andrews
@ 2015-11-03 15:57                     ` Bart Schaefer
  2015-11-04 14:48                       ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-03 15:57 UTC (permalink / raw)
  To: zsh-users

On Nov 2,  3:01pm, Ray Andrews wrote:
} Subject: Re: easy calling of associative array?
}
} On 11/02/2015 01:05 PM, Bart Schaefer wrote:
} >
} >      typeset -g ary[idx]=val
} >
} > Ordinarly "typeset" inside a function body behaves like "local".  The
} > -g option tells it not to do that, so that the name "ary" is taken to
} > come from the calling context instead of the current function context.
} 
} I don't understand. The idea of context here is new to me. Why is
} 'ary' not a variable like any other?

Parameters have dynamic scope from the function call (not the function
name) where they are declared.  So if you have a function "upper" that
calls a function "middle" that calls a function "lower", a parameter that
is declared in "middle" is visible to "lower" but not to "upper", and a
parameter declared in "upper" is visible to both "middle" and "lower".

"typeset" is the generic "declare a parameter" builtin.  All of the other
builtins (delcare, local, integer, etc.) are special cases of "typeset".

So if both "upper" and "middle" contain "typeset -A ary", the name "ary"
in "middle" is now a new variable, not the same as the "ary" in "upper".
This is exactly like saying "local ary" in "middle", becuse "local" is
really a form of "typeset", merely given another name to make it more
obvious what's happening.

Using "typeset -gA ary" in "middle" prevents this; it says "don't declare
a new local parameter, use the one that is already in scope."

The usage with "-g ary[idx]" says "don't attempt to index into a new local
parameter $ary, instead index into the existing $ary if there is one." 
Which is what you want if the name "ary" has been passed down through $1.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-03 15:57                     ` Bart Schaefer
@ 2015-11-04 14:48                       ` Ray Andrews
  2015-11-04 16:39                         ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Ray Andrews @ 2015-11-04 14:48 UTC (permalink / raw)
  To: zsh-users

On 11/03/2015 07:57 AM, Bart Schaefer wrote:
> Using "typeset -gA ary" in "middle" prevents this; it says "don't declare
> a new local parameter, use the one that is already in scope."
>
> The usage with "-g ary[idx]" says "don't attempt to index into a new local
> parameter $ary, instead index into the existing $ary if there is one."
> Which is what you want if the name "ary" has been passed down through $1.
>
Ok, that's quite clear.  Thanks Bart.  Historian that I am, I expect 
that if the writers of the first shells realized how far their work 
would evolve, they'd have introduced rigorous C-ish scoping and typing 
at the getgo, since largeish projects sure could use it.  One is often 
unsure what is going on with variables when there are several  levels of 
functions.  This use of typeset sounds like excellent insurance.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-04 14:48                       ` Ray Andrews
@ 2015-11-04 16:39                         ` Bart Schaefer
  2015-11-04 18:31                           ` Ray Andrews
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2015-11-04 16:39 UTC (permalink / raw)
  To: zsh-users

On Nov 4,  6:48am, Ray Andrews wrote:
}
} Historian that I am, I expect that if the writers of the first shells
} realized how far their work would evolve, they'd have introduced
} rigorous C-ish scoping and typing at the getgo, since largeish
} projects sure could use it.

Historically no one would have written that sort of project in shell;
that's what C was for.  Even functions are a bolt-on to the original
shells; there was no scoping to consider at the time.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: easy calling of associative array?
  2015-11-04 16:39                         ` Bart Schaefer
@ 2015-11-04 18:31                           ` Ray Andrews
  0 siblings, 0 replies; 20+ messages in thread
From: Ray Andrews @ 2015-11-04 18:31 UTC (permalink / raw)
  To: zsh-users

On 11/04/2015 08:39 AM, Bart Schaefer wrote:
> On Nov 4,  6:48am, Ray Andrews wrote:
> }
> } Historian that I am, I expect that if the writers of the first shells
> } realized how far their work would evolve, they'd have introduced
> } rigorous C-ish scoping and typing at the getgo, since largeish
> } projects sure could use it.
>
> Historically no one would have written that sort of project in shell;
> that's what C was for.  Even functions are a bolt-on to the original
> shells; there was no scoping to consider at the time.
Yeah, that's about what I was saying. Interesting how things evolve past 
what their body plans are really designed for (fruit bats, rhinoceros 
beetles, London street plan), and how those body plans adapt to cope 
with it.  I do now quite understand that there is a limit to how big a 
zsh project should get to be.  Still you know, will all these fantastic 
little build in manipulations that zsh can perform, one might long for 
something that combines that power with the robustness of C type 
checking and so on.  Dunno, maybe that's Python or Ruby--haven't looked 
at them yet.  But the experiments I'm doing now are cool, I've pretty 
much got data arrays being passed by what more or less amounts to a 
'pointer' to look at it tho of course it ain't really a pointer, so it 
satisfies.

>


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-11-04 18:31 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-01 23:12 easy calling of associative array? Ray Andrews
2015-11-01 23:55 ` ZyX
2015-11-02  0:49   ` Ray Andrews
2015-11-02  3:08     ` Bart Schaefer
2015-11-02  3:33       ` Ray Andrews
2015-11-02  6:51         ` Bart Schaefer
2015-11-02 15:43           ` Ray Andrews
2015-11-02 16:28             ` Bart Schaefer
2015-11-02 18:32               ` Ray Andrews
2015-11-02 19:37                 ` ZyX
2015-11-02 22:10                   ` Bart Schaefer
2015-11-02 22:50                     ` Ray Andrews
2015-11-02 21:05                 ` Bart Schaefer
2015-11-02 23:01                   ` Ray Andrews
2015-11-03 15:57                     ` Bart Schaefer
2015-11-04 14:48                       ` Ray Andrews
2015-11-04 16:39                         ` Bart Schaefer
2015-11-04 18:31                           ` Ray Andrews
2015-11-02 19:33             ` ZyX
2015-11-02 23:04               ` Ray Andrews

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).