module BusinessFlow::DSL::ClassMethods
Contains the DSL
for BusinessFlow
Public Instance Methods
# File lib/business_flow/dsl.rb, line 114 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
# File lib/business_flow/dsl.rb, line 103 def call(parameter_object = {}) execute(build(parameter_object)) end
# File lib/business_flow/dsl.rb, line 123 def call!(*args) flow = call(*args) raise FlowFailedException, flow if flow.errors? flow end
:reek: UtilityFunction This is a function on us so that other modules can change execution behavior.
# File lib/business_flow/dsl.rb, line 109 def execute(flow) catch(:halt_step) { flow.call } unless flow.errors? result_from(flow) end
# File lib/business_flow/dsl.rb, line 171 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
# File lib/business_flow/dsl.rb, line 155 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
# File lib/business_flow/dsl.rb, line 72 def inputs @inputs ||= Inputs.new(self) end
# File lib/business_flow/dsl.rb, line 141 def instrument(_name, _flow) yield nil end
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.
# File lib/business_flow/dsl.rb, line 57 def lookup(field, by:, with:) by = Array.wrap(by) optional(*by) wants field, with, unless: -> { by.any? { |input| send(input).nil? } }, default_output: field end
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?
@param fields The fields required from the initialization parameters
# File lib/business_flow/dsl.rb, line 42 def needs(*fields) inputs.add_needs(fields) end
# File lib/business_flow/dsl.rb, line 161 def needs_code needs.map do |need| %(if #{need}.nil? errors[:#{need}] << 'must not be nil' throw :halt_step end ) end.join("\n") end
Allows a field to be retieved form the initialization paramters, but does not require it to be non-nil
# File lib/business_flow/dsl.rb, line 48 def optional(*fields) inputs.add_optional(fields) end
Declares that you will expose a field to the outside world.
# File lib/business_flow/dsl.rb, line 77 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
# File lib/business_flow/dsl.rb, line 145 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
: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
# File lib/business_flow/dsl.rb, line 96 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
# File lib/business_flow/dsl.rb, line 133 def step_executor(executor_class = nil) if executor_class @executor_class = executor_class else @executor_class ||= ::BusinessFlow::DefaultStepExecutor end end
# File lib/business_flow/dsl.rb, line 129 def step_queue @step_queue ||= [] end
: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
# File lib/business_flow/dsl.rb, line 87 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
Allows a field to be retrieved from the initialiaztion parameters
# File lib/business_flow/dsl.rb, line 65 def wants(field, default = nil, opts = {}, &blk) internal_name = "wants_#{field}".to_sym default = proc { nil } unless default || block_given? uses(internal_name, default, opts, &blk) inputs.add_wants(ParameterField.new(field, internal_name)) end