Module: FlowOrganizer::Context
- Defined in:
- lib/flow_organizer/context.rb
Overview
Handle context operations.
Class Method Summary collapse
-
.clear_parameter_cache ⇒ Object
Drops every cached parameter spec.
-
.compute_parameter_spec(callable:) ⇒ Object
private
Compute the slice spec for a callable from its keyword parameter list.
-
.generate_callable_ctx(callable:, ctx:) ⇒ Object
private
Extract needed key from the organizer context to send them to the callable.
-
.get_parameters(callable:) ⇒ Object
Given a ‘callable`, get its `parameters` data.
-
.parameter_cache ⇒ Object
private
Memoized ‘callable => slice_spec` map.
-
.update_context(ctx:, local_ctx:) ⇒ Object
private
Performs a 1 level deep merge on the organizer context.
-
.update_context!(ctx:, local_ctx:) ⇒ Object
private
In-place variant of ‘update_context`.
Class Method Details
.clear_parameter_cache ⇒ Object
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.
This id done by using introspection on the callable.
Extract needed key from the organizer context to send them to the callable.
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_cache ⇒ 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.
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.
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 |