executor: a per-element operator joins on IFS[0], not a space (#752) - #753
Merged
Conversation
`"${arr[*]}"` joins its elements on the first character of IFS. Applying a
per-element operator made it join on a hardcoded space instead, so the two
forms disagreed side by side:
IFS=,; arr=(ab xy)
${arr[*]} -> ab,xy
${arr[*]#a} -> b xy bash: b,xy
An empty IFS was wrong in the other direction: it must concatenate with no
separator at all, and produced spaces.
The right primitives already existed and are used at five other join sites.
ifs_join_separator carries the load-bearing unset-vs-empty distinction --
unset IFS means a space, an EMPTY IFS means no separator -- which is why the
append is guarded on the separator's LENGTH rather than assuming one byte.
They were introduced by #518 to retire exactly these hardcoded-space joins;
this site was missed because it lives in the operator dispatch rather than in
the plain vector path.
The FIELD COUNT is a separate defect and is deliberately untouched:
`"${arr[@]}"` with an operator should contribute N fields rather than being
joined at all (#749). This join is what a `[*]` form legitimately wants, and
the comment says so, so a later reader does not mistake it for a decision
about `[@]`.
tests/integration/test_vector_substitution_spec.c gains 9 checks: a custom IFS
across the operator families, positionals, the EMPTY-IFS concatenation and the
UNSET-IFS space, the operator-free form that must not change, a single element
needing no separator, and an empty array. 5 of the file's 26 checks fail
against the parent build.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Closes #752.
The defect
"${arr[*]}"joins on the first character of IFS. With a per-element operator applied it joined on a hardcoded space, so the two forms disagreed side by side:An empty IFS was wrong in the other direction — it must concatenate with no separator, and produced spaces.
The primitive already existed
ifs_join_separatorandjoin_strings_with_separe used at five other join sites, introduced by #518 to retire exactly these hardcoded-space joins. This site was missed because it lives in the operator dispatch rather than in the plain vector path.ifs_join_separatorcarries the load-bearing unset-vs-empty distinction (unset → space, empty → no separator), which is why the append is guarded on the separator's length rather than assuming one byte.Field count deliberately untouched
"${arr[@]}"with an operator should contribute N fields rather than being joined at all — that is #749, and it is a different question in a different place. This join is what a[*]form legitimately wants; the code comment says so explicitly, so a later reader does not mistake it for a decision about[@].Verification
#,^^,//), positionals, the empty-IFS concatenation and the unset-IFS space, the operator-free form that must not change, a single element needing no separator, and an empty array.