Module: Igniter::Extensions::Contracts::Language::PiecewisePack

Defined in:
lib/igniter/extensions/contracts/language/piecewise_pack.rb

Defined Under Namespace

Classes: Definition

Constant Summary collapse

UNSET =
Object.new.freeze

Class Method Summary collapse

Class Method Details

.install_into(kernel) ⇒ Object



19
20
21
22
# File 'lib/igniter/extensions/contracts/language/piecewise_pack.rb', line 19

def install_into(kernel)
  kernel.dsl_keywords.register(:piecewise, piecewise_keyword)
  kernel
end

.invoke_value(callable_or_value, kwargs) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/igniter/extensions/contracts/language/piecewise_pack.rb', line 54

def invoke_value(callable_or_value, kwargs)
  return callable_or_value unless callable_or_value.respond_to?(:call)

  parameters = callable_or_value.parameters
  accepts_any_keywords = parameters.any? { |kind, _name| kind == :keyrest }
  return callable_or_value.call(**kwargs) if accepts_any_keywords

  accepted = parameters.select { |kind, _name| %i[key keyreq].include?(kind) }.map(&:last)
  callable_or_value.call(**kwargs.slice(*accepted))
end

.manifestObject



12
13
14
15
16
17
# File 'lib/igniter/extensions/contracts/language/piecewise_pack.rb', line 12

def manifest
  Igniter::Contracts::PackManifest.new(
    name: :extensions_language_piecewise,
    registry_contracts: [Igniter::Contracts::PackManifest.dsl_keyword(:piecewise)]
  )
end

.piecewise_keywordObject



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/igniter/extensions/contracts/language/piecewise_pack.rb', line 24

def piecewise_keyword
  Igniter::Contracts::DslKeyword.new(:piecewise) do |name, on:, builder:, depends_on: [], decision: nil, &block|
    raise ArgumentError, "piecewise :#{name} requires a block" unless block

    selector_name = on.to_sym
    decision_name = (decision || :"#{name}_decision").to_sym
    dependency_names = [selector_name, *Array(depends_on).map(&:to_sym)].uniq
    definition = Definition.new(name: name, selector_name: selector_name)
    definition.instance_eval(&block)
    definition.validate!

    builder.add_operation(
      kind: :compute,
      name: decision_name,
      depends_on: dependency_names,
      callable: lambda do |**values|
        definition.resolve(values)
      end
    )
    builder.add_operation(
      kind: :compute,
      name: name,
      depends_on: [decision_name],
      callable: lambda do |**values|
        values.fetch(decision_name).fetch(:value)
      end
    )
  end
end