Module: Hecks::Facade::Surface::Chapter
- Included in:
- Hecks::Facade::Surface
- Defined in:
- lib/hecks/facade/surface/chapter.rb
Overview
One chapter's module: vision and aggregate roll-call on the singleton, one aggregate door per declared head, and the declaration hook for names the door does not carry.
Instance Method Summary collapse
Instance Method Details
#chapter_module(dispatcher, bluebook) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/hecks/facade/surface/chapter.rb', line 12 def chapter_module(dispatcher, bluebook) chapter = Module.new chapter.define_singleton_method(:vision) { bluebook.vision } chapter.define_singleton_method(:aggregates) { bluebook.aggregates.map(&:name).sort } # THE CHAPTER, EXPLAINING ITSELF. `Projector::DocsProjector` reads # nothing but this bluebook's own IR, so the document cannot drift # from the domain — the same guarantee `bin/reference` gives the DSL # reference by generating it from the Syntax chapter. # # A METHOD RATHER THAN ONLY A SCRIPT because that is what gets it # read: `QualityControl.docs` in a console, beside `vision` and # `aggregates`, at the moment somebody is wondering what a verb # wants. Projected on each call rather than memoised — it is a pure # read of the IR, and a stale document is the entire thing this # exists to prevent. chapter.define_singleton_method(:docs) do |**| Projector.call(:docs, bluebook: bluebook, options: ) end # THE CHAPTER, READ BACK IN ENGLISH — `Projector::NarrateProjector` # beside `:docs`, for the reader who needs to confirm the domain is # right rather than call it: `QualityControl.narrate` in a console. chapter.define_singleton_method(:narrate) do |**| Projector.call(:narrate, bluebook: bluebook, options: ) end # THE DOMAIN'S OWN IR, PROJECTED. `Projector` has taken # `call(name, bluebook:, options:)` since §30, but nothing could # reach it from a booted domain — this module already closes # over the one `Bluebook` every projector wants and simply # never handed it out, so every bin/ projector rebuilt a # Registry and reloaded the files to recover what was already # sitting here. # # Pizzas.project(Projections::OIDC) # Pizzas.project(Projections::Shape, out: "shape.json") # # No `to_ir` companion: `project(Projections::IR)` already # answers with the canonical serialized form, and handing out # the live graph as well would be a second way to say the same # thing. Anything genuinely needing the graph is a projector, # and a projector is given it. # # `out:` writes and everything else is passed through to the # target — so `options` stays the projector's own vocabulary # (`audience:` for OIDC) rather than a fixed set this method # would have to know about. chapter.define_singleton_method(:project) do |target, out: nil, **| key = Projector.key_for(target) artifact = Projector.call(key, bluebook: bluebook, options: ) return artifact unless out Projector.write(artifact, out, as: Projector.emits_for(key)) end bluebook.aggregates.each do |aggregate| chapter.const_set(aggregate.hecks_name, aggregate_module(dispatcher, bluebook.name, aggregate)) end # INSIDE A HECKSAGON, A NAME IS A DECLARATION, NOT A LOOKUP. A # `.hecksagon` may name an aggregate this door does not carry — a STALE # door from an earlier boot resolving another registry's chapter, the # exact hazard the constant tree used to hide by reinstalling on every # load. With a collector open, the name becomes a `BindingProxy` # recording the same bind the aggregate module would ; without one, it # is a genuine NameError, exactly as before. # # THE OTHER READER OF A MISS is S0b's own bridge (docs/dsl-work- # slices.md, const_shim.rb's `ScopedConstant`): a bluebook still being # DECLARED that names `#{bluebook.name}::Something` — an event, a # command reference, an `admits:` — reaches HERE, not # `Object.const_missing`, the moment this chapter's own facade already # exists (a previous boot in the same process, or this same chapter # re-entering its own name). `ConstShim.active?` is exactly as true # here as it is at the top level, mid-declaration, and consulting the # SAME resolver is what makes a scoped reference resolve identically # whether or not a facade happens to be built yet — the earlier # attempt's own failure mode (this file's own history) was a bridge # that worked only BEFORE any facade existed. chapter.define_singleton_method(:const_missing) do |name| collector = Bluebook::DSL::HecksagonBuilder.collector return Bluebook::DSL::BindingProxy.new("#{bluebook.name}::#{name}", collector) if collector resolver = Bluebook::DSL::ConstShim.resolver return resolver.call("#{bluebook.name}::#{name}") if resolver super(name) end chapter end |