Module: FlowOrganizer::Context

Defined in:
lib/flow_organizer/context.rb

Overview

Handle context operations.

Class Method Summary collapse

Class Method Details

.clear_parameter_cacheObject

Drops every cached parameter spec. Useful for tests, benchmarks, and code reloading scenarios where stale Method objects should not be retained.



107
108
109
# File 'lib/flow_organizer/context.rb', line 107

def self.clear_parameter_cache
  @parameter_cache = {}
end

.compute_parameter_spec(callable:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Compute the slice spec for a callable from its keyword parameter list.

Returns one of:

- `:keyrest`         the callable accepts `**`, pass the full ctx
- `:none`            the callable accepts nothing, pass nil
- `Array<Symbol>`    the kw arg names to slice from the ctx


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/flow_organizer/context.rb', line 80

def self.compute_parameter_spec(callable:)
  parameters = get_parameters(callable:)
  by_type    = parameters.group_by { |el| el[0] }

  if (by_type.keys - [:keyreq, :key, :keyrest]).size > 0
    raise FlowOrganizer::Error.new('FlowOrganizer only supports methods with keyword arguments')
  end

  if by_type[:keyrest]
    :keyrest
  elsif by_type[:keyreq] || by_type[:key]
    ((by_type[:keyreq] || []).map { |el| el[1] }) + ((by_type[:key] || []).map { |el| el[1] })
  else
    :none
  end
end

.generate_callable_ctx(callable:, ctx:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

This id done by using introspection on the callable.

Extract needed key from the organizer context to send them to the callable.

Examples:

generate_callable_ctx(callable: ->(a:), { a: 1, b: 2, c: 3 }) => { a: 1 }
generate_callable_ctx(callable: ->(a:, **), { a: 1, b: 2, c: 3 }) => { a: 1, b: 2, c: 3 }


47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/flow_organizer/context.rb', line 47

def self.generate_callable_ctx(callable:, ctx:)
  spec = parameter_cache[callable] ||= compute_parameter_spec(callable:)

  case spec
  when :keyrest
    ctx.dup
  when :none
    nil
  else
    ctx.slice(*spec)
  end
end

.get_parameters(callable:) ⇒ Object

Given a ‘callable`, get its `parameters` data



61
62
63
64
65
66
67
68
69
70
# File 'lib/flow_organizer/context.rb', line 61

def self.get_parameters(callable:)
  if callable.is_a?(Proc) || callable.is_a?(Method)
    callable.parameters
  elsif callable.respond_to?(:call)
    callable.method(:call).parameters
  else
    # NOTE: this should not be callable :)
    raise FlowOrganizer::Error.new("Unsupported callable #{ callable.class } `#{ callable }`")
  end
end

.parameter_cacheObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Memoized ‘callable => slice_spec` map. Method/Proc objects with identical signatures hash and compare equal, so they collapse to one cache entry.



101
102
103
# File 'lib/flow_organizer/context.rb', line 101

def self.parameter_cache
  @parameter_cache ||= {}
end

.update_context(ctx:, local_ctx:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

The content of the ‘:errors` key is merged manually.

Performs a 1 level deep merge on the organizer context.



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/flow_organizer/context.rb', line 8

def self.update_context(ctx:, local_ctx:)
  local_ctx ||= {}
  ctx_errors  = ctx[:errors]

  # NOTE: 1 level deep only (not a deep merge)
  ctx = ctx.merge(local_ctx)

  if ctx_errors
    ctx[:errors] = ctx_errors + (local_ctx[:errors] || [])
  end

  ctx
end

.update_context!(ctx:, local_ctx:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

In-place variant of ‘update_context`. The caller must already own `ctx` (e.g. it was `dup`ed at the top of `FlowOrganizer.call`). Used on the dispatch hot path to avoid allocating a fresh hash per callable.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/flow_organizer/context.rb', line 26

def self.update_context!(ctx:, local_ctx:)
  return ctx if local_ctx.nil? || local_ctx.empty?

  ctx_errors   = ctx[:errors]
  local_errors = local_ctx[:errors]

  ctx.merge!(local_ctx)

  if ctx_errors
    ctx[:errors] = ctx_errors + (local_errors || [])
  end

  ctx
end