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
strings:

  # No need for backslashes here...

  filters=(
    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%%:*}"
    done
  }

> 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

    filters=(
      ...
    )

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

  _arguments \
    $_ecasound_opts \
    ...                # other options



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

Bye
 Sven


--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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