docs(zsh-standard): require capturing a parameter before localizing it - #603
Merged
Conversation
z-shell/zi lost a working search path twice in one function for the same
reason, and nothing in the standard covered it.
zi#477 removed this as dead:
local +h FPATH=$PLUGINS_DIR${fpath_elements:+:...}:$FPATH
local +h -a fpath
fpath=( $PLUGIN_DIR $fpath_elements $fpath )
It was not. `fpath' and `FPATH' are tied, so the scalar assignment already
created the local pair populated with the caller's value, and the `local +h -a
fpath' that follows does not reset it because the parameter is by then already
local to that scope. Remove the scalar and the array declaration creates a fresh
empty array, `$fpath' on the right-hand side expands to nothing, and the
assignment silently truncates itself to $PLUGIN_DIR. Immediate `autoload +X' of
any function the loading plug-in did not own then stopped resolving.
Two properties combine, each individually easy to misread: a second `local' on a
parameter already local to the same scope is not a reset, and localizing a tied
parameter starts it empty so `x=( new $x )' self-truncates. Together they make a
load-bearing line look inert, and deleting it changes behaviour with no error.
zsh/parameters/avoid-special-name-collisions already names the path/PATH tie,
but only to warn against repurposing the name; nothing covered what the tie does
to localization. The same shape applies to path, cdpath, manpath, and
module_path.
Add zsh/parameters/capture-before-localizing to the parameters section, with the
matching object in lib/zsh-standard-policy.json and both ordered inventories in
the validator. The frozen consumer-parser golden moves accordingly: the rule
count goes from 64 to 65, startup-file membership from 49 to 50, and the digest
is replaced as scripts/test_validate_zsh_standard_policy.py instructs.
Evidence: z-shell/zi#488, fixed in z-shell/zi#491.
Closes #602
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
zsh/parameters/capture-before-localizingto the Zsh Scripting Standard. Documentation and policy only; no behaviour change in this repository.Why
z-shell/zilost a working search path twice in one function for the same reason, and nothing in the standard covered it.zi#477 removed this as dead:
It was not dead.
fpathandFPATHare tied, so the scalar assignment already created the local pair populated with the caller's value, and thelocal +h -a fpaththat follows does not reset it because the parameter is by then already local to that scope. Remove the scalar and the array declaration creates a fresh empty array,$fpathon the right-hand side expands to nothing, and the assignment silently truncates itself to$PLUGIN_DIR. Reproduced on zsh 5.9.2:Immediate
autoload +Xof any function the loading plug-in did not own then stopped resolving, which brokeAloxaf/fzf-tabcompletely. Tracked as zi#488, fixed in zi#491.Two properties combine, and each is individually easy to misread. A second
localon a parameter already local to the same scope is not a reset, so the declaration order looks redundant when it is load-bearing. And localizing a tied parameter starts it empty, so the common idiomx=( new $x )self-truncates rather than extending. Together they produce a construct where deleting an apparently inert line changes behaviour with no error and no diagnostic.zsh/parameters/avoid-special-name-collisionsalready names thepath/PATHtie, but only to warn against repurposing the name. Nothing covered what the tie does to localization. The same shape applies topath,cdpath,manpath, andmodule_path.What changed
The rule in
.github/instructions/zsh-scripting.instructions.md, its object inlib/zsh-standard-policy.json, and both ordered inventories inscripts/validate-zsh-standard-policy.py(NORMATIVE_RULE_IDSandSTARTUP_PROFILE_RULE_IDS).The frozen consumer-parser golden moves with it, exactly as
scripts/test_validate_zsh_standard_policy.pyinstructs when a rule is added: block count 64 to 65,startup-filemembership 49 to 50, and the digest replaced with the reported actual.Verification
Closes #602