Replace internal requires with Ruby autoload (#120) - #121
Merged
Conversation
Fixes the circular require between OrganizationType and Subdivision reported under Ruby 4.0 with warnings enabled: organization_type.rb:16: circular require considered harmful - subdivision.rb OrganizationType.included did `require_relative "subdivision"` inside the hook while Subdivision opens with `include OrganizationType`, so loading subdivision re-entered the hook and re-required the in-progress file. Wire the model + converter layer via a central autoload manifest (lib/relaton/bib/model_autoload.rb) instead of require_relative chains, making load order irrelevant. Both include orders now resolve because each class opens its own constant before the include fires the hook that references it. - Move `require "lutaml/model"/"lutaml/xml"` and the Lutaml::Model::Config XML adapter block out of item.rb into the manifest (eager), so serialization works regardless of which model class is referenced first. - Drop the `class Relation < Serializable` forward stub from item.rb; make relation.rb self-contained and autoloaded. - Keep require_relative only for converter method-partials (reopens, which autoload cannot express). - Add spec/relaton/bib/autoload_spec.rb covering structural, functional, load-order-independence, and a -W2 circular-require guard.
relaton-render now requires Ruby >= 3.3.0; the integration job pinned 3.2, so bundler version-resolution failed before any test ran.
Passing multi-line Ruby with embedded quotes via `ruby -e` is mangled during Windows command-line reconstruction (newlines/quotes lost), so the load-order subprocess tests produced empty stdout and failed only on windows-latest. Write the snippet to a Tempfile and run `ruby <file>` instead, which behaves identically across platforms; strip stdout to tolerate CRLF.
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.
Summary
Fixes #120 — the circular require between
OrganizationTypeandSubdivisionreported by downstream gems (metanorma-taste) under Ruby 4.0 with warnings:OrganizationType.includeddidrequire_relative "subdivision"inside the hook, whileSubdivisionopens withinclude OrganizationType— so loadingsubdivision.rbre-entered the hook and re-required the in-progress file.Per @ronaldtse's direction on the issue, this replaces the internal
require_relativechains with Rubyautoloadvia a central manifest, which makes load order irrelevant and removes this whole class of ordering bugs.Changes
lib/relaton/bib/model_autoload.rb— centralautoloadmanifest for everyRelaton::Bibmodel +Converterconstant. Also eagerlyrequireslutaml/model/lutaml/xmland runs theLutaml::Model::Config.configure { xml_adapter_type = :nokogiri }block (moved out ofitem.rb) so serialization works regardless of which class is referenced first.item.rb— dropped the ~39-linerequire_relativeblock and theclass Relation < Serializable; endforward stub.relation.rb— now self-contained (class Relation < Lutaml::Model::Serializable), autoloaded.organization_type.rb— deleted the in-hookrequire_relative "subdivision"(the core fix).require_relativefromcontact,ext,organization,date,series,bibitem,bibdata,bibitem_shared,bibdata_shared.require_relativefor converter method-partials (reopens, whichautoloadcannot express).CLAUDE.md.Why it resolves the cycle
In both include orders,
class Subdivision < Serializable/class Organization < Serializableopens its own constant before theinclude OrganizationTypethat fires the hook referencingSubdivision— so the self-reference resolves to an already-open constant instead of re-triggering the load.Tests
New
spec/relaton/bib/autoload_spec.rb:Relationsuperclass, and nokogiri-adapter guards;Subdivision-first andOrganization-first);-W2subprocess guard asserting no relaton-bibcircular requirewarning (scoped so unrelated third-party warnings don't false-fail).Full suite: 229 examples, 0 failures. RuboCop clean on new files.