Skip to content

fix: stop singularize() turning psychoanalyses into psychoanalyasis - #4188

Merged
bpamiri merged 3 commits into
developfrom
peter/singularize-analyses
Oct 5, 2026
Merged

bpamiri merged 3 commits into
developfrom
peter/singularize-analyses

Conversation

@bpamiri

@bpamiri bpamiri commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #4187

Summary

The singularize rule ((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$ → \1\2sis added group 2, the leading a of analy, a second time. So psychoanalyses came back as psychoanalyasis. The rule is now (analy|ba|diagno|parenthe|progno|synop|the)ses$ → \1sis.

For the other alternatives group 2 was empty, and a bare analyses is caught by the earlier (^analy)ses$ rule. So output changes only for a word that ends in analyses without starting with it.

Upgrade notes

  • The changelog fragment is a changed one (changelog.d/4187-singularize-prefixed-analyses.changed.md), because singularize() output changes for words ending in analyses without starting with it.
  • The 4.1 to 4.2 upgrade guide gets an entry under "Behaviour changes to check".

Test plan

  • New spec. vendor/wheels/tests/specs/global/SingularizeSesRuleSpec.cfc checks that prefixed -analyses words are fixed. It also pins analyses, bases, diagnoses, parentheses, prognoses, synopses, theses and hypotheses to their current output.
  • RED on develop: Lucee 7 and BoxLang each fail 1 spec (psychoanalyses → psychoanalyasis).
  • GREEN: 2/2 on Lucee 7 and BoxLang.
  • global directory (pass / fail / error):
Engine Result
Lucee 7 307 / 0 / 0
Lucee 6 307 / 0 / 0
Adobe ColdFusion 2023 306 / 0 / 0
Adobe ColdFusion 2025 306 / 0 / 0
BoxLang 307 / 0 / 0
RustCFML v0.693.0 306 / 0 / 0
  • Full suite (tools/test-local.sh, Lucee 7 + SQLite): 6524 passed.

  • After merging develop (for 4.2): global specs (SQLite) 310 / 0 / 0 on Lucee 7, Lucee 6 and BoxLang, 309 / 0 / 0 on Adobe 2023, Adobe 2025 and RustCFML v0.693.0; full core suite, Lucee 7 + SQLite: 6664 passed; guides build passes.

🤖 Generated with Claude Code

The -ses singularize rule replaced with \1\2sis, and group 2 was the leading "a" of the analy
alternative, so a prefixed -analyses word got that letter twice. The inner groups are dropped and
the replacement is \1sis. Other -ses words are unchanged.

Fixes #4187

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
@bpamiri bpamiri added this to the v4.3.0 milestone Oct 3, 2026
@bpamiri

bpamiri commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

rev1-r1 review @ c0caee1 (draft, 4.3): APPROVE on code; merge gated on compat-matrix run 37113979661 and on 4.2.0 shipping.

((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$ → \1\2sis becomes (analy|ba|diagno|parenthe|progno|synop|the)ses$ → \1sis.

  • The old \2 was a bug. Group 1 already holds the whole stem, and group 2 is the (a) of the analy alternative only. So "…analyses" (anything the anchored (^analy)ses$ rule above doesn't catch, such as psychoanalyses) became "…analyasis". For every other stem \2 was unset: empty on Lucee and Adobe, and BoxLang's unset-group error (the same class as pluralize() throws on BoxLang for words ending in -ex, -lf or -rf #4185) for bases, theses, diagnoses, parentheses, prognoses, synopses.
  • The new rule gives stem + sis for all of them. Plain analyses is unaffected, since the earlier anchored rule still takes it.
  • The spec covers the prefixed analyses case and the other stems, and is RED on Lucee 7 and BoxLang.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Wheels Test Results

216 679 tests   212 555 ✅  1h 8m 8s ⏱️
 16 576 suites    4 124 💤
     32 files          0 ❌

Results for commit 331c195.

♻️ This comment has been updated with latest results.

@bpamiri

bpamiri commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator Author

rev1-r1 correction: in my review above I said the unset \2 made BoxLang throw for bases/theses/diagnoses/…. That's wrong. BoxLang only throws when group 1 is unset (#4185), and on develop those words already return basis/thesis/diagnosis on BoxLang. So #4188 fixes wrong output on every engine (psychoanalyses → psychoanalyasis), not a crash. Matrix 37113979661 on c0caee1 is fully green: all 32 legs discovered 497 bundles with 0 failures and 0 errors, SingularizeSesRuleSpec is 2/2 on every leg, and RustCFML and the gate are green. OK to merge once it leaves draft after the 4.2.0 cut.

bpamiri and others added 2 commits October 4, 2026 21:04
Moves the fragment to `changed`, since the output of singularize()
changes for words ending in "analyses", and adds an entry under
"Behaviour changes to check" in the 4.1 to 4.2 upgrade guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
@bpamiri bpamiri modified the milestones: v4.3.0, v4.2.0 Oct 5, 2026
@bpamiri
bpamiri marked this pull request as ready for review October 5, 2026 04:24
@bpamiri

bpamiri commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Final: APPROVE @ 331c195 (lifted into 4.2; matrix 37263380571, all 32 legs read)

Delta since my approval at c0caee1

  • The code is identical.
  • The develop merge has one combined hunk in global/strings.cfm, because fix: stop pluralize() throwing on BoxLang for -ex, -lf and -rf words #4186 changed the adjacent pluralize rule list. It is a pure take-both: the merged pluralize line equals develop's, and the singularize line equals c0caee1's.
  • The new 4.1→4.2 guide entry is accurate. Only a non-anchored …analyses word was misspelled. bases, theses, diagnoses and the rest come out unchanged.
  • The fragment is retyped to changed.

Matrix

No open findings.

@bpamiri
bpamiri merged commit 4cdf712 into develop Oct 5, 2026
72 checks passed
@bpamiri
bpamiri deleted the peter/singularize-analyses branch October 5, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

singularize() returns "psychoanalyasis" for "psychoanalyses"

1 participant