You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have often wished for the ability to directly reference an outer-scope parameter (bypassing any local parameters of the same name). This would be most useful for supporting functions that take the name of a parameter to be acted upon. Consider the following:
# Assign a value to the named association# $1 => the name of the association to assign tomkassoc() {
local -A a_
a_=( foo 1 bar 2 ) # Pretend this is useful:${(PAA)1::="${(@kv)a_}"}
}
# This workslocal -A a; mkassoc a
# This doesn't — it only modifies a_ in the local scopelocal -A a_; mkassoc a_
What i'd like is some feature — whether an expansion flag or an option to typeset — that tells zsh to use the outer-scope version of the parameter.
I was able to get this working for parameter reads pretty easily (only like five lines of code changed), but parameter writes (as in the above example) are more difficult because those are performed by name only. Many parts of the code seem to have the expectation that they'll be able to access the correct parameter by name, in fact.
The only way i can think of to get around that (besides fucking with the whole API) is maybe like making a clone of the original parameter but with some special prefix to the name that can't be used by a real parameter (like outer/). But that feels shitty. idk.
In the mean time, there are only two feasible work-arounds that i know of:
Prefix or suffix all of the function's local variables by a string of characters that's unlikely to be used in an outer scope. In order to allow two such functions to call each other, the strings would have to be pretty unique — maybe the first four characters of the base32 of the raw output from a hash of the function name. Even then, the function would still break if it called itself recursively.
Use a function EXIT trap (in combination with some very careful quoting) to set the outer-scope parameter after the function has returned to the calling scope. The setting of the parameter itself should be quite reliable, but you would still have issues if you needed to do anything with the parameter from inside the function (like check to see if it's defined).
The text was updated successfully, but these errors were encountered:
Oliver's almost-finished implementation of namerefs from workers/15058 would at least partially address this, since it retains the local level of the referenced parameter at the time of definition.
It's not a complete solution for me, though, since it can't work with special parameters like argv (which are set automatically when entering a new function scope), and even for normal parameters, you have to define the reference before any locals, which precludes it from working quite reliably in conjunction with argument parsing and similar.
It could be an inspiration though; at the very least it shows how to resolve outer-scope parameters.
I have often wished for the ability to directly reference an outer-scope parameter (bypassing any local parameters of the same name). This would be most useful for supporting functions that take the name of a parameter to be acted upon. Consider the following:
What i'd like is some feature — whether an expansion flag or an option to
typeset
— that tells zsh to use the outer-scope version of the parameter.I was able to get this working for parameter reads pretty easily (only like five lines of code changed), but parameter writes (as in the above example) are more difficult because those are performed by name only. Many parts of the code seem to have the expectation that they'll be able to access the correct parameter by name, in fact.
The only way i can think of to get around that (besides fucking with the whole API) is maybe like making a clone of the original parameter but with some special prefix to the name that can't be used by a real parameter (like
outer/
). But that feels shitty. idk.In the mean time, there are only two feasible work-arounds that i know of:
Prefix or suffix all of the function's local variables by a string of characters that's unlikely to be used in an outer scope. In order to allow two such functions to call each other, the strings would have to be pretty unique — maybe the first four characters of the base32 of the raw output from a hash of the function name. Even then, the function would still break if it called itself recursively.
Use a function
EXIT
trap (in combination with some very careful quoting) to set the outer-scope parameter after the function has returned to the calling scope. The setting of the parameter itself should be quite reliable, but you would still have issues if you needed to do anything with the parameter from inside the function (like check to see if it's defined).The text was updated successfully, but these errors were encountered: