Make InheritableSetting's raw stores internal (series finale)#2810
Merged
Conversation
Danger ReportNo issues found. |
ericproulx
force-pushed
the
inheritable-setting-finale
branch
from
July 21, 2026 12:32
b008c25 to
4aec25e
Compare
ericproulx
changed the base branch from
inheritable-setting-integration
to
master
July 21, 2026 12:32
ericproulx
added a commit
that referenced
this pull request
Jul 21, 2026
It had been inserted right after #2796 by an early scripted edit, landing ahead of #2797-#2808 instead of after them. Also drops a duplicate #2807 entry left over from the integration branch's history (one plain, one with the vestigial-hash-copy note added later). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ericproulx
added a commit
that referenced
this pull request
Jul 23, 2026
It had been inserted right after #2796 by an early scripted edit, landing ahead of #2797-#2808 instead of after them. Also drops a duplicate #2807 entry left over from the integration branch's history (one plain, one with the vestigial-hash-copy note added later). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ericproulx
force-pushed
the
inheritable-setting-finale
branch
from
July 23, 2026 01:37
ec60dbd to
6d088f0
Compare
Enforce the per-key encapsulation that the semantic accessors already provide: `namespace_inheritable` is now protected and `namespace_stackable_with_hash` private, so every `namespace_inheritable` key is reachable only through its dedicated accessor. Internal code reads the `@namespace_inheritable` / `@namespace_stackable` ivars directly; the protected/public readers exist for inherit_from / copy_state_from peer access. `namespace_stackable` deliberately stays a public reader: grape-swagger reads it directly (and walks its inherited_values chain). Treat it as read-only from the outside and prefer the dedicated accessors. Two supporting changes: * `Router::Pattern::Path` no longer receives a merged dump of both stores; `Endpoint#to_routes` passes the new `InheritableSetting#path_settings` snapshot — a `PathSettings` value object (`Data`) carrying exactly the six values `Path` reads. * `InheritableSetting#mount_paths` exposes the full mount-path stack, complementing `#mount_path` (outermost entry only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ericproulx
force-pushed
the
inheritable-setting-finale
branch
from
July 23, 2026 01:41
6d088f0 to
e808748
Compare
dblock
approved these changes
Jul 24, 2026
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.
The finale of the
InheritableSettingencapsulation series (targets the #2809 integration branch; #2795–#2808 built the accessor catalog): the raw stores become internal where the ecosystem allows.namespace_inheritableis now protected andnamespace_stackable_with_hashprivate — every inheritable key is reachable only through its dedicated accessor.namespace_stackabledeliberately stays public but deprecated: grape-swagger reads it directly (see below), so external reads warn throughGrape.deprecatorwith a pointer to the semantic accessors, while Grape itself reads the underlying ivar (peer access ininherit_from/copy_state_fromgoes through a protected raw reader) and never warns. The reader gets removed or narrowed in a future major once grape-swagger migrates; a spec pins the deprecation. Theroute/namespace/globalscratch stores (backingroute_setting/namespace_setting/global_setting) also stay public.Commits
path_settings— the last raw consumer,Endpoint#prepare_default_path_settings, merged full dumps of both stores per endpoint whileRouter::Pattern::Pathreads exactly six values (full mount-path stack, root prefix, format, raw content-types stack, version, version options).InheritableSetting#path_settingssnapshots precisely those into aGrape::Util::InheritableSetting::PathSettingsvalue object (a plainData.define, no keyword defaults — unlikeRescueOptions/VersionOptions, it has no bare-default production caller, since its sole constructor always supplies all six members; a mistyped or omitted member fails loudly instead of returning nil),to_routesuses it, the old method is deleted, andPathreads typed members with nil-tolerant guards replacing thekey?-presence checks (equivalent under always-present members — verified case by case). Two semantics deliberately preserved:mount_pathis the full stack (unlike the scalar#mount_pathaccessor, which is.firstfor the versioner), via.presenceso an unmounted API still contributes no path part; andcontent_typesstays the raw registration stack becauseArray(...).size == 1counts registrations, not distinct formats — a latent duplicate-registration quirk flagged for a separate fix rather than silently changed here.namespace_inheritablemoves toprotected(peer access ininherit_from/copy_state_fromkeeps working), the deep-merge helper toprivate. No spec reaches around the visibility: the storage-engine specs exercise the inheritable store's semantics (inheritance, nearest-wins, point-in-time copies, to_hash) through public accessors (root_prefix,format,version_options) instead of raw keys, and an unused captured-settings hash ininside_route_spec's endpoint dummy is removed.path_settingscloses the catalog as the one cross-cutting projection, and the class doc now describes what the class has become: the settings registry whose accessor naming encodes semantics (add_*= stacking,== nearest-wins scalar,!/?= flag).mount_paths+ docs — a public reader for the full mount-path stack (used bypath_settings, and the migration target for grape-swagger below), plus CHANGELOG/UPGRADING.grape-swagger (found by code search — the reason
namespace_stackablestays public)grape-swagger's current master reaches into
namespace_stackablein three files. Nothing breaks with this PR — the reads now emit a deprecation warning pointing at the accessors; the table below is the migration:swagger_documentation_adder.rbnamespace_stackable[:namespace]/[:mount_path]inheritable_setting.namespaces.last/inheritable_setting.mount_paths.join('/')token_owner_resolver.rbnamespace_stackable[:helpers]behindrespond_to?inheritable_setting.helpersrequest_param_parsers/route.rbStackableValues#inherited_valueschain manually for per-scope paramsInheritableSetting) — not a mechanical renameBooks
Metrics/ClassLength330 → 340 (path_settings+mount_pathsland the class at 331 lines).🤖 Generated with Claude Code