Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Backticks and other tricks

Mario Lang wrote:

> Can anyone cast some light on the following questions
> regarding the code below:
> 1. Why does ${(P)...[...]} not work with subscripts of the
> array? (in fucntion argsargs).

`array', that's the point.  The ${(P)1} yields an array (a *normal*
array, not an associative array).  On normal arrays the subscripts of
`[ef1]' etc. are used as mathematical expressions and since there
aren't any variables with those names, mathematical evaluation gives
the value `0' (zero) as subscripts, so one always gets the first
element in the array.

Currently I don't see a solution other than just not using an
associative array at all, e.g. by prepending the `keys' to the

  # No need for backslashes here...

    ef1:"Resonant bandpass filter":"center frequency":Hz:"width":Hz
    ef3:"Resonant lowpass filter":"cutoff frequency":Hz:resonance::gain:
    ef4:"Resonant lowpass filter (3rd-order, 36dB)":"cutoff frequency":Hz:resonance:
    efa:"Allpass filter":"delay":samples:"feedback":percents
    efb:"Bandpass filter":"center frequency":Hz:"width":Hz
    efc:"Comb filter":"delay":samples:"radius":0-1
    efh:"Highpass filter":"cutoff frequency":Hz
    efi:"Inverse comb filter":"delay":samples:"radius":0-1
    efl:"Lowpass filter":"cutoff frequency":Hz
    efr:"Bandreject filter":"center frequency":Hz:"width":Hz
    efs:"Resonator (resonating bandpass filter)":"center frequency":Hz:"width":Hz\

  argsargs () {
    for i in ${(P)1}; do
      print -- "*-${i%%:*}[${${i#*:}%%:*}]: :->${i%%:*}"

> 2. Why does the inclusion trick with backticks not
> work (`argsargs filters`). Actually _arguments complains
> about not being able to parse this option. 

The backticks make the words in the output of argsargs be split at
white spaces.  One solution would be to set IFS (deprecated) or use
the standard expression for splitting process outputs into lines:

  ${(f)"$(argsargs filters)"}

The quoting around the $(..) makes it return the complete output as
one (unaltered) string.  The (f) flag splits that at newlines into
array elements.

But anyway I would suggest not using process substitution if it can be 
avoided (always an extra process).  And since the options don't change 
it can be cached without any harm.  E.g.:

  if (( ! $+_ecasound_opts )); then
    local filters i


    for i in $filters; do
      _ecasound_opts=($_ecasound_opts "*-${i%%:*}[${${i#*:}%%:*}]: :->${i%%:*}")

  _arguments \
    $_ecasound_opts \
    ...                # other options

To -workers: that the ${(P)1} thing doesn't work is ugly, isn't it?


Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx

Messages sorted by: Reverse Date, Date, Thread, Author