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

Function wrappers around "typeset"

Ordinarily if you use "typeset" in a function, any parameters it
creates are in the current function scope and can't be seen outside.
This can be amended by using "typeset -g" but then the parameter is
created at the farthest enclosing scope where it already exists, or
the true global scope if it doesn't exist anywhere in between.

So what can you do if you want to create a parameter only one function
scope up the stack?

You can take advantage of the special semantics of the "trap" command.

createparam() {
  emulate -L zsh
  trap 'typeset '${(j: :)${(qq)@}} EXIT

The drawback is that you can only use the syntax of the builtin
typeset command, not those of the reserved word typeset -- so you
CANNOT for example

createparam -a foo=(a b c)

Obviously this "createparam" is a silly example, why would you not
make an alias or use typeset directly?  Suppose you want to change or
augment the arguments of typeset:

tieparam() {
  emulate -L zsh
  trap 'typeset -T '${(j: :)${(qq)@}} EXIT
tieparam FOO=a:b:c foo

It also works to push the typeset out of the caller's scope, e.g.

tieparam -g FOO=axbxc foo x

This "tieparam" is still a simple example, but there are other cases
where "deferred typeset" might come in handy.  Of course this same
trap-EXIT trick works to defer any command to the calling scope as
long as it's the last command the called function needs to perform
(and you remember to carefully quote any parameter references to
substitute them in the correct scope).

Also be careful with the options (hence "emulate -L zsh") or your EXIT
trap might remain set in a scope where you don't want it.

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