zsh-users
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh Users <zsh-users@zsh.org>
Subject: Function wrappers around "typeset"
Date: Thu, 26 Jan 2023 12:42:00 -0800	[thread overview]
Message-ID: <CAH+w=7bpQKOHSOiARDAC2EvBpcm1gqwaR6KjA4a6sDRkag_xbQ@mail.gmail.com> (raw)

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.


                 reply	other threads:[~2023-01-26 20:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7bpQKOHSOiARDAC2EvBpcm1gqwaR6KjA4a6sDRkag_xbQ@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=zsh-users@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).