Module: BusinessFlow::DSL::ClassMethods
- Defined in:
- lib/business_flow/dsl.rb
Overview
Contains the DSL for BusinessFlow
Defined Under Namespace
Classes: Inputs
Instance Method Summary collapse
- #build(parameter_object) ⇒ Object
- #call(parameter_object = {}) ⇒ Object
- #call!(*args) ⇒ Object
-
#execute(flow) ⇒ Object
:reek:UtilityFunction This is a function on us so that other modules can change execution behavior.
- #finalize_initializer ⇒ Object
- #finalize_result_provider ⇒ Object
- #inputs ⇒ Object
- #instrument(_name, _flow) {|nil| ... } ⇒ Object
-
#lookup(field, by:, with:, inputs: nil, output: nil) ⇒ Object
Provides an alternate way to look up the value for a field.
-
#needs(*fields) ⇒ Object
Requires that a field be retrievable from the initialization parameters.
-
#needs_code ⇒ Object
rubocop:disable Metrics/MethodLength.
-
#optional(*fields) ⇒ Object
Allows a field to be retieved form the initialization paramters, but does not require it to be non-nil.
-
#provides(*fields) ⇒ Object
Declares that you will expose a field to the outside world.
- #result_from(flow) ⇒ Object
-
#step(klass, opts = {}, &blk) ⇒ Object
:reek:ControlParameter It’s just nicer to have this fall back to a block than have a different DSL method when using/not using blocks.
- #step_executor(executor_class = nil) ⇒ Object
- #step_queue ⇒ Object
-
#uses(field, klass = nil, opts = {}, &blk) ⇒ Object
:reek:ControlParameter It’s just nicer to have this fall back to a block than have a different DSL method when using/not using blocks.
-
#wants(field, default = nil, opts = {}, &blk) ⇒ Object
Allows a field to be retrieved from the initialiaztion parameters.
Instance Method Details
#build(parameter_object) ⇒ Object
120 121 122 123 124 125 126 127 |
# File 'lib/business_flow/dsl.rb', line 120 def build(parameter_object) finalize_initializer allocate.tap do |flow| catch(:halt_step) do flow.send(:_business_flow_dsl_initialize, parameter_object) end end end |
#call(parameter_object = {}) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/business_flow/dsl.rb', line 106 def call(parameter_object = {}) flow = build(parameter_object) return result_from(flow) if flow.errors? execute(flow) end |
#call!(*args) ⇒ Object
129 130 131 132 133 134 |
# File 'lib/business_flow/dsl.rb', line 129 def call!(*args) flow = call(*args) raise FlowFailedException, flow if flow.errors? flow end |
#execute(flow) ⇒ Object
:reek:UtilityFunction This is a function on us so that other modules can change execution behavior.
115 116 117 118 |
# File 'lib/business_flow/dsl.rb', line 115 def execute(flow) catch(:halt_step) { flow.call } unless flow.errors? result_from(flow) end |
#finalize_initializer ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/business_flow/dsl.rb', line 187 def finalize_initializer return if @finalized_initializer class_eval %{ private def _business_flow_dsl_initialize(parameter_object) @parameter_object = parameter_object #{needs_code} initialize end }, __FILE__, __LINE__ - 6 @finalized_initializer = true end |
#finalize_result_provider ⇒ Object
162 163 164 165 166 167 |
# File 'lib/business_flow/dsl.rb', line 162 def finalize_result_provider return if @finalized_result_provider || !@result_copy const_get(:Result).class_eval "#{@result_copy}\nend", __FILE__, __LINE__ @finalized_result_provider = true end |
#inputs ⇒ Object
75 76 77 |
# File 'lib/business_flow/dsl.rb', line 75 def inputs @inputs ||= Inputs.new(self) end |
#instrument(_name, _flow) {|nil| ... } ⇒ Object
148 149 150 |
# File 'lib/business_flow/dsl.rb', line 148 def instrument(_name, _flow) yield nil end |
#lookup(field, by:, with:, inputs: nil, output: nil) ⇒ Object
Provides an alternate way to look up the value for a field. This can be thought of as using a ‘wants’ combined with an expectation of presence, without having to check for whether or not the wants can be executed.
:reek:NilCheck This is one of the places where we eliminate nil. :reek:LongParameterList Deal with it
60 61 62 63 64 65 |
# File 'lib/business_flow/dsl.rb', line 60 def lookup(field, by:, with:, inputs: nil, output: nil) by = Array.wrap(by) optional(*by) wants field, with, unless: -> { by.any? { |input| send(input).nil? } }, default_output: field, inputs: inputs, output: output end |
#needs(*fields) ⇒ Object
Requires that a field be retrievable from the initialization parameters
This will only require that the field is not nil. The field may still be #empty?
44 45 46 |
# File 'lib/business_flow/dsl.rb', line 44 def needs(*fields) inputs.add_needs(fields) end |
#needs_code ⇒ Object
rubocop:disable Metrics/MethodLength
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/business_flow/dsl.rb', line 169 def needs_code # rubocop:disable Metrics/MethodLength needs.map do |need| if BusinessFlow.active_model5? %(if #{need}.nil? errors.add(:#{need}, :invalid, message: 'must not be nil') throw :halt_step end ) else %(if #{need}.nil? errors.add(:#{need}, 'must not be nil') throw :halt_step end ) end end.join("\n") end |
#optional(*fields) ⇒ Object
Allows a field to be retieved form the initialization paramters, but does not require it to be non-nil
50 51 52 |
# File 'lib/business_flow/dsl.rb', line 50 def optional(*fields) inputs.add_optional(fields) end |
#provides(*fields) ⇒ Object
Declares that you will expose a field to the outside world.
80 81 82 83 84 85 86 |
# File 'lib/business_flow/dsl.rb', line 80 def provides(*fields) @provides ||= FieldList.new([], PublicField, [self, const_get(:Result)]) @result_copy ||= FROM_FLOW_PREAMBLE @result_copy += fields.map { |field| "\n@#{field} = flow.#{field}" } .join @provides.add_fields(fields) end |
#result_from(flow) ⇒ Object
152 153 154 155 156 157 158 159 160 |
# File 'lib/business_flow/dsl.rb', line 152 def result_from(flow) finalize_result_provider unless @finalized_result_provider # We use instance_variable_get here instead of making it part of # from_flow to ensure that we do not create the errors object unless # we need it. result = const_get(:Result).new(flow.instance_variable_get(:@errors)) result.from_flow(flow) if @result_copy result end |
#step(klass, opts = {}, &blk) ⇒ Object
:reek:ControlParameter It’s just nicer to have this fall back to a block than have a different DSL method when using/not using blocks
99 100 101 102 103 104 |
# File 'lib/business_flow/dsl.rb', line 99 def step(klass, opts = {}, &blk) step = Step.new(Callable.new(blk || klass), opts) step_queue.push(step) step.output_fields .each { |field| Field.new(field).add_to(self) } end |
#step_executor(executor_class = nil) ⇒ Object
140 141 142 143 144 145 146 |
# File 'lib/business_flow/dsl.rb', line 140 def step_executor(executor_class = nil) if executor_class @step_executor = executor_class else @step_executor ||= ::BusinessFlow::DefaultStepExecutor end end |
#step_queue ⇒ Object
136 137 138 |
# File 'lib/business_flow/dsl.rb', line 136 def step_queue @step_queue ||= [] end |
#uses(field, klass = nil, opts = {}, &blk) ⇒ Object
:reek:ControlParameter It’s just nicer to have this fall back to a block than have a different DSL method when using/not using blocks
90 91 92 93 94 95 |
# File 'lib/business_flow/dsl.rb', line 90 def uses(field, klass = nil, opts = {}, &blk) step = Step.new(Callable.new(klass || blk), { default_output: field }.merge(opts)) retriever = proc { step.call(self).merge_into(self) } UsesField.new(field, retriever).add_to(self) end |
#wants(field, default = nil, opts = {}, &blk) ⇒ Object
Allows a field to be retrieved from the initialiaztion parameters
68 69 70 71 72 73 |
# File 'lib/business_flow/dsl.rb', line 68 def wants(field, default = nil, opts = {}, &blk) internal_name = :"wants_#{field}" default = proc {} unless default || block_given? uses(internal_name, default, opts, &blk) inputs.add_wants(ParameterField.new(field, internal_name)) end |