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).