Class: Hecks::Bluebook::DSL::ProcessManagerBuilder::HandlerBuilder

Inherits:
Object
  • Object
show all
Includes:
WordGate
Defined in:
lib/hecks/bluebook/dsl/process_manager_builder.rb

Defined Under Namespace

Classes: DispatchBuilder

Constant Summary collapse

GRAMMAR_CONTEXT =
"Handler"

Constants included from WordGate

WordGate::NOT_ADMITTED

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHandlerBuilder

Returns a new instance of HandlerBuilder.



223
# File 'lib/hecks/bluebook/dsl/process_manager_builder.rb', line 223

def initialize = @dispatches = []

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Hecks::Bluebook::DSL::WordGate

Instance Attribute Details

#dispatchesObject (readonly)

Returns the value of attribute dispatches.



219
220
221
# File 'lib/hecks/bluebook/dsl/process_manager_builder.rb', line 219

def dispatches
  @dispatches
end

Instance Method Details

#dispatch_impl(command_ref, with: nil, &block) ⇒ Object

THE COMMAND ITSELF (ADR 0025, "events and reactions" — command references become first-class), same shape and same reasons as PolicyBuilder#trigger's own header — bare constant live, quoted text only under shadow-parsing (S0a's bridge; frozen era text still writes dispatch "Banking::Account.Debit").

RENAMED FROM dispatch — item #13's full metaprogrammed dispatch (slice 4), same reasoning as trigger_impl above.

AN OPTIONAL BLOCK OPENS compensates ON THIS DISPATCH SPECIFICALLY — per-dispatch saga compensation, replacing a hand-written list at the saga's own on :refused leg. Real, live bug this closes: examples/banking/bluebook/transfers_ and_payments.bluebook's own Settlement saga wrote a compensating reversal by hand that depended on an event only fired if someone dispatched it manually — "the reversal was written and never armed" (that file's own comment). The runtime now tracks which legs actually completed (SagaInterpreter's own completed_compensations) and compensates only those, newest first, instead of trusting an author's static list to be complete and correctly ordered.



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/hecks/bluebook/dsl/process_manager_builder.rb', line 246

def dispatch_impl(command_ref, with: nil, &block)
  if command_ref.is_a?(::String) && !MetaValidator.shadow_parsing?
    raise InvalidProcessManager,
          "dispatch #{command_ref.inspect} is quoted text — give the bare command constant " \
          "instead, e.g. dispatch Account::Debit"
  end

  spec = DispatchSpec.new(
    command_name: Naming.command_ref(command_ref),
    with_spec:    (with || {}).to_a
  )
  spec.instance_variable_set(:@projection_declared, !with.nil?)

  if block
    builder = DispatchBuilder.new
    builder.instance_eval(&block)
    # `instance_variable_get`, not a public `compensates_spec`
    # reader — a public one would be a method the grammar
    # never declares, exactly what `spec/syntax_conformance_
    # spec.rb`'s "answers only words the language declares"
    # check exists to catch.
    spec.compensates = builder.instance_variable_get(:@compensates_spec)
  end

  @dispatches << spec
  spec
end