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

Mysteriously changing parameters and options within a function.



Consider the following function whose purpose is mostly evident:

check-missing-locals() {
  local -A parms_before options_before ignored_params
  local i xit
  xit=0
  ignored_params=(parms_before 1
  		      options_before 1
  		      parameters 1
  		      i 1
  		      xit 1
  		      parameters 1
  		      functions 1
  		      aliases 1
  		      galiases 1
  		      history 1
  		      historywords 1
  		      widgets 1
  		      options 1
                      modules 1
  		      LINENO 1
  		      ERRNO 1
  		      RANDOM 1
  		      TTYIDLE 1
  		      SECONDS 1
  		      status 1
  		      '?' 1
  		      _ 1
  		      pipestatus 1
  	       )
  for i in ${(k)parameters}
  do
    (( $+ignored_params[$i] )) && continue
    parms_before[$i]=${(P)i}
  done
  options_before=(${(kv)options})
  eval $*
  for i in ${(ko)options}
  do
    if [[ $options[$i] != $options_before[$i] ]]
    then
      echo "$0: changed option $i: $options_before[$i] " \
           "vs. $options[$i]" 1>&2
      xit=1
    fi
  done
  for i in ${(ko)parms_before}
  do
    (( $+ignored_params[$i] )) && continue
    if (( ! $+parameters[$i] ))
    then
      echo "$0: unset parameter $i" 1>&2
      xit=1
    fi
  done
  for i in ${(ko)parameters}
  do
    (( $+ignored_params[$i] )) && continue
    if (( ! $+parms_before[$i] ))
    then
      echo "$0: set parameter $i" 1>&2
      xit=1
    fi
  done
  for i in ${(ko)parms_before}
  do
    (( $+ignored_params[$i] )) && continue
    if (( $+parameters[$i] && $+parms_before[$i] )) \
       && [[ ${(P)i} != $parms_before[$i] ]]
    then
      echo "$0: changed parameter $i: ${(q)parms_before[$i]}" \
           " vs. ${(qP)i}" 1>&2
      xit=1
    fi
  done
  return $xit
}

Its purpose is to detect if any command (or function actually) has
forgotten to declare a parameter or option as local.

Eg. (intended,.but not actual output):

  % check-missing-locals somevar=1 
  check-missing-locals: set parameter somevar
  % check-missing-locals somevar=2
  check-missing-locals: changed parameter somevar: 1  vs. 2
  % check-missing-locals unset somevar
  check-missing-locals: unset parameter somevar
  % check-missing-locals setopt octal_zeroes
  check-missing-locals: changed option octalzeroes: off  vs. on

However, I get this:

% check-missing-locals :
check-missing-locals: changed option braceexpand: on  vs. off
check-missing-locals: unset parameter LANG
check-missing-locals: unset parameter LC_ALL
check-missing-locals: unset parameter LC_COLLATE
check-missing-locals: unset parameter LC_CTYPE
check-missing-locals: unset parameter LC_MESSAGES
check-missing-locals: unset parameter LC_NUMERIC
check-missing-locals: unset parameter LC_TIME

What makes LANG, LC_* and the braceexpand option appear to be in
different states at the beginning and the end of the function?

Phil.



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