Class: Hecks::Bluebook::DSL::DomainPortBuilder
- Inherits:
-
Object
- Object
- Hecks::Bluebook::DSL::DomainPortBuilder
- Includes:
- WordGate
- Defined in:
- lib/hecks/bluebook/dsl/domain_port_builder.rb
Constant Summary collapse
- GRAMMAR_CONTEXT =
"DomainPort"
Constants included from WordGate
Class Method Summary collapse
Instance Method Summary collapse
-
#answers(name) ⇒ Object
THE METHOD CONTRACT —
PortBuilder#answers's own twin, added here after the fact: a.portfile migrated to parse through this builder (the repointlib/hecks.rb#port's own comment describes) can still declare one (extraction.port's ownanswers :canonical, real, live corpus text) — this builder's bare-verb fallback needs to carry it through to the samePortobjectPortBuilderitself would have built, or the migration would silently drop a method-contract check for any.portfile that uses this word. -
#asks_impl(name, to: nil, &block) ⇒ Object
WHAT WE ASK OF THE OUTSIDE — the direction this language did not have.
- #build ⇒ Object
-
#initialize(name, owner: nil, legacy_bare_port: false) ⇒ DomainPortBuilder
constructor
legacy_bare_port:— ONLYHecks.port's own top-level method (lib/hecks.rb) passestrue. - #signal(value) ⇒ Object
-
#tells_impl(name, to: nil, &block) ⇒ Object
WHAT THE OUTSIDE TELLS US — an external fact arriving, translated into this domain's own word for it.
-
#verb(value) ⇒ Object
Hecks.port "x" do verb "y"; signal :effect end's own two words, reachable here too — a bare-verbDomainPortBuilder.buildfalls back to the SAMEPortobjectPortBuilderproduces (build, below), so any.portfile can migrate to being parsed by this builder with zero change to its own text, or to any caller that reads.verb/.signaloff thePortit gets back.
Constructor Details
#initialize(name, owner: nil, legacy_bare_port: false) ⇒ DomainPortBuilder
legacy_bare_port: — ONLY Hecks.port's own top-level method
(lib/hecks.rb) passes true. PortBuilder#build never refused
an empty build (no verb, no signal, nothing) — Port.new(verb: nil, signal: :reply) is a real, allowed shape dsl_spec.rb's own
"a port" tests rely on (signal-only, no verb at all). The
AGGREGATE-scoped (BindingProxy#port) and hecksagon-ROOT
(HecksagonBuilder#port_impl) callers both reach this SAME
class with owner: nil too when they're building the bare-verb
shape (port_impl's own root-level port can be EITHER shape,
decided only after build returns) — so owner.nil? cannot be
the discriminator between "old Hecks.port semantics" and "real
DomainPort semantics"; those two callers correctly want the
stricter "declares no verb and no operations" refusal build
already raises below, unchanged. Only the literal top-level
.port file caller wants the older, looser rule.
25 26 27 28 29 30 31 32 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 25 def initialize(name, owner: nil, legacy_bare_port: false) @name = name @owner = owner @operations = [] @signal = :reply @answers = [] @legacy_bare_port = end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Hecks::Bluebook::DSL::WordGate
Class Method Details
.build(name, owner: nil, legacy_bare_port: false, &block) ⇒ Object
113 114 115 116 117 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 113 def self.build(name, owner: nil, legacy_bare_port: false, &block) builder = new(name, owner: owner, legacy_bare_port: ) builder.instance_eval(&block) if block builder.build end |
Instance Method Details
#answers(name) ⇒ Object
THE METHOD CONTRACT — PortBuilder#answers's own twin, added
here after the fact: a .port file migrated to parse through
this builder (the repoint lib/hecks.rb#port's own comment
describes) can still declare one (extraction.port's own
answers :canonical, real, live corpus text) — this builder's
bare-verb fallback needs to carry it through to the same Port
object PortBuilder itself would have built, or the migration
would silently drop a method-contract check for any .port
file that uses this word.
101 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 101 def answers(name) = @answers << name.to_sym |
#asks_impl(name, to: nil, &block) ⇒ Object
WHAT WE ASK OF THE OUTSIDE — the direction this language did not
have. Before this, a domain could be CALLED by an adapter and never
call one. An asks is dispatched like any other port operation, so
a policy can trigger it off an event, and it comes back as one of
the two events it named — which is what makes the outside world
something the model can reason about rather than a place exceptions
come from.
RENAMED FROM asks — item #13's full metaprogrammed dispatch
(slice 4c), same reasoning as tells_impl above.
60 61 62 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 60 def asks_impl(name, to: nil, &block) @operations << PortOperationBuilder.build(name, to: to, owner: @owner, direction: :outbound, &block) end |
#build ⇒ Object
103 104 105 106 107 108 109 110 111 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 103 def build raise Malformed, "#{@name} declares both a verb and operations — a port is one or the other, not both" if @verb && !@operations.empty? return MetaValidator.call_port(Port.new(name: @name, verb: @verb, signal: @signal, answers: @answers)) if @verb || (@legacy_bare_port && @operations.empty?) raise Malformed, "#{@name} declares no verb and no operations" if @operations.empty? DomainPort.new(name: @name, operations: @operations) end |
#signal(value) ⇒ Object
90 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 90 def signal(value) = @signal = value.to_sym |
#tells_impl(name, to: nil, &block) ⇒ Object
WHAT THE OUTSIDE TELLS US — an external fact arriving, translated
into this domain's own word for it. Spelled operation before it
had a twin, and operation still works: the corpus is full of it,
and renaming a word costs every chapter that uses it for no gain a
reader can feel.
RENAMED FROM tells — item #13's full metaprogrammed dispatch
(slice 4c). operation/tells are TWO separate Keyword rows
(a word admitting two forms) that both name calls: "tells_impl"
— the routing between the two spellings now lives in the table,
not in a Ruby alias. Not bootstrap-reachable (checked
directly), so no BOOTSTRAP_CALLS_FALLBACK entry needed.
46 47 48 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 46 def tells_impl(name, to: nil, &block) @operations << PortOperationBuilder.build(name, to: to, owner: @owner, direction: :inbound, &block) end |
#verb(value) ⇒ Object
Hecks.port "x" do verb "y"; signal :effect end's own two words,
reachable here too — a bare-verb DomainPortBuilder.build falls
back to the SAME Port object PortBuilder produces (build,
below), so any .port file can migrate to being parsed by this
builder with zero change to its own text, or to any caller that
reads .verb/.signal off the Port it gets back. Ordinary
defs, exactly like PortBuilder's own — WordGate's own
header is explicit that a word answered this way never reaches
its method_missing, so no new self-hosted grammar row is
needed for either word under this context.
89 |
# File 'lib/hecks/bluebook/dsl/domain_port_builder.rb', line 89 def verb(value) = @verb = value.to_s |