fix(ruby): stop sub-SDKs named after Ruby or SDK constants from shadowing them
Why
Generated Ruby code lives inside the SDK module, and every tag becomes a sub-SDK class directly under it. Unqualified constant references in the templates therefore resolved to a same-named sub-SDK instead of the intended constant:
File.extname,Time.now,Date.iso8601,is_a? Hashand similar failedsrb tcwhen a spec had aFile,Time,DateorHashtag.include Kernelmade the gem fail to load when a spec had aKerneltag.- A
UtilsorSDKHookstag replaced the SDK's own module (Utils is not a class). AnSDKConfigurationtag overwrotesdkconfiguration.rband the@sdk_configurationinstance variable.
What changed
- Ruby core and stdlib constants (
::String,::JSON,::File,::StandardError, ...) are prefixed with::in the SDK templates and in the TypeScript helpers that emit Ruby code. - Usage snippets are top-level Ruby, so their date, date-time, file and environment variable example values stay unqualified (
rubyConstantRef). Model defaults and generated tests keep the prefix. - Sub-SDKs whose class or file name matches an SDK internal (
Utils,SDKHooks,SDKConfiguration,sdkconfiguration.rb) get anSDKsuffix, repeated until the name is free of every other sub-SDK and the main SDK file (subSDKTypeName). A sub-SDK accessor namedsdk_configurationbecomessdk_configuration_(sanitizeSubSDKFieldName). - Schemas keep their names: models live under
Models::and do not shadow these constants. - New snapshot tests, each compiled with
srb tcand rubocop:TestSnapRubySubSDKCoreConstantCollision: tagsFile,Time,Hash,Class,Kernel,Utils,Date,String,Array,SDKConfiguration,SDKHooks,UtilsSDK.TestSnapRubySubSDKReservedNameNesting:sdkClassName: UtilsSDKwith aUtilstag (sub-SDK becomesUtilsSDKSDK), plus nested groupsadmin.SDKConfigurationandadmin.SDKHooks.TestSnapRubyCoreConstantExampleValues: date, date-time and file example values stay unqualified inUSAGE.mdand use::in generated tests.
- Existing Ruby namespace snapshots are updated for the
::prefixes. - Ruby review SDK regenerated. The diff contains only
::qualification, formatter re-wrapping and the matchinggen.lockchecksums.
Drive-by: date and date-time doc links
Unrelated to the shadowing fix. Ruby docs linked date fields to DateTime and date-time fields to Date. templates/templates/ruby/includes/documentation.ts now swaps them back, with its own changeset (docs, patch). In the review SDK this only changes four docs pages and their gen.lock checksums.
Testing
go test ./pkg/generate/snapshots/namespaces/ -run Ruby -count=1with Ruby 3.2.11 and Go 1.26.10: all 6 Ruby snapshot tests generate, compile (srb tc, rubocop) and match.make lintsteps: prettier,go mod tidy -diff,tsgofor the Ruby templates and golangci-lint all pass.- Each reserved tag (
Utils,SDKHooks,SDKConfiguration,sdk_configuration) was generated with main and with this branch, then loaded withSDK.new. On main, all four fail to load (Utils is not a class,SDKHooks is not a module,wrong number of arguments (given 1, expected 6)). On this branch they load and the accessors return the renamed sub-SDKs. The renames therefore only affect SDKs that could not be used before. TARGET=review make build-rubypasses (srb tc, rubocop, mock-server build and staticcheck).- A large production-scale spec with many tags regenerates and passes
srb tcand rubocop (5039 files, no offenses).
Known and out of scope: the tag pair SDKConfiguration + sdkconfiguration (already renamed upstream to SDKConfiguration1 / Sdkconfiguration2) still fails at runtime because attr_accessor is derived from Type.Name while the instance variable is derived from FieldName. This mismatch predates this change.
Public-safety check
- This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
- Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (
.claude/skills/public-repo-communication/SKILL.md). - Generated fixtures and review SDK changes are public-safe.
- I reviewed
git diff --check.