Class: Hecks::Bluebook::DSL::BindingProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/hecks/bluebook/dsl/binding_proxy.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fqn, collector) ⇒ BindingProxy

Returns a new instance of BindingProxy.



13
14
15
16
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 13

def initialize(fqn, collector)
  @fqn       = fqn
  @collector = collector
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(verb, *args, **kwargs, &block) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 54

def method_missing(verb, *args, **kwargs, &block)
  @collector << Bind.new(
    aggregate: @fqn,
    verb:      verb.to_s,
    adapter:   args.first.to_s,
    role:      kwargs[:role]&.to_s
  )
  block&.call
  self
end

Class Method Details

.namespace(domain, collector) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 5

def self.namespace(domain, collector)
  Module.new do
    define_singleton_method(:const_missing) do |aggregate|
      BindingProxy.new("#{domain}::#{aggregate}", collector)
    end
  end
end

Instance Method Details

#port(name, &block) ⇒ Object

THE AGGREGATE-SCOPED PORT — Payments::Payment.port("Gateway") do ... end, the same receiver a plain bind like .persisted_by(...) already reaches, because a port belongs to exactly one aggregate the same way a bind does. A REAL method, not method_missing : its shape (a name and a block building operations) has nothing to do with Bind, so it does not belong in that generic verb path.



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
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 24

def port(name, &block)
  domain, aggregate_name = @fqn.split("::")
  aggregate_ir = Hecks.current_registry.bluebook(domain)&.aggregate(aggregate_name) or
    raise Malformed, "#{@fqn} declares no such aggregate — a port needs one to belong to"

  # See HecksagonBuilder#port's own comment on why this resolver
  # swap is needed : ConstShim's active resolver is one global for
  # the whole dynamic extent, and it is currently this file's own
  # BindingProxy-minting one, which would turn a bare `Pizza` inside
  # `reference_to Pizza` into another BindingProxy instead of a name.
  built = ConstShim.with(->(const) { const }) { DomainPortBuilder.build(name, owner: aggregate_name, &block) }

  # A `verb`-shaped port is a plain `Port` — the exact struct
  # `Hecks.port`'s own top-level method registers, so it goes
  # through the same `add_port` the registry already answers for
  # that call. It belongs to no aggregate IR the way an
  # operations-shaped `DomainPort` does; the aggregate above
  # was only needed to resolve `owner` for the operations branch.
  if built.is_a?(Port)
    Hecks.current_registry.add_port(built)
    return self
  end

  built.operations.each do |operation|
    operation.attributes.select(&:reference?).each { |attribute| attribute.type.declared_in = aggregate_ir }
  end
  aggregate_ir.add_port(built)
  self
end

#respond_to_missing?(_name, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


65
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 65

def respond_to_missing?(_name, _include_private = false) = true

#to_sObject



67
# File 'lib/hecks/bluebook/dsl/binding_proxy.rb', line 67

def to_s = @fqn