Module: Cuprum::Steps
Overview
The Steps supports step by step processes that halt on a failed step.
After including Cuprum::Steps, use the #steps instance method to wrap a series of instructions. Each instruction is then defined using the #step method. Steps can be defined either as a block or as a method invocation.
When the steps block is evaluated, each step is called in sequence. If the step resolves to a passing result, the result value is returned and execution continues to the next step. If all of the steps pass, then the result of the final step is returned from the #steps block.
Conversely, if any step resolves to a failing result, that failing result is immediately returned from the #steps block. No further steps will be called.
For example, consider updating a database record using a primary key and an attributes hash. Broken down into its basics, this requires the following instructions:
-
Using the primary key, find the existing record in the database.
-
Update the record object with the given attributes.
-
Save the updated record back to the database.
Note that each of these steps can fail for different reasons. For example, if a record with the given primary key does not exist in the database, then the first instruction will fail, and the follow up steps should not be executed. Further, whatever context is executing these steps probably wants to know which step failed, and why.
Instance Method Summary collapse
-
#step { ... } ⇒ Object
Executes the block and returns the value, or halts on a failure.
-
#steps { ... } ⇒ Cuprum::Result
Returns the first failing #step result, or the final result if none fail.
Instance Method Details
#step { ... } ⇒ Object
Executes the block and returns the value, or halts on a failure.
The #step method is used to evaluate a sequence of processes, and to fail fast and halt processing if any of the steps returns a failing result. Each invocation of #step should be wrapped in a #steps block, or used inside the #process method of a Command.
If the object returned by the block is a Cuprum result or compatible object (such as a called operation), the value is converted to a Cuprum result via the #to_cuprum_result method. Otherwise, the object is returned directly from #step.
If the returned object is a passing result, the #value of the result is returned by #step.
If the returned object is a failing result, then #step will throw :cuprum_failed_result and the failing result. This is caught by the #steps block, and halts execution of any subsequent steps.
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/cuprum/steps.rb', line 108 def step raise ArgumentError, 'expected a block' unless block_given? result = yield return result unless result.respond_to?(:to_cuprum_result) result = result.to_cuprum_result return result.value if result.success? throw :cuprum_failed_step, result end |
#steps { ... } ⇒ Cuprum::Result
Returns the first failing #step result, or the final result if none fail.
The #steps method is used to wrap a series of #step calls. Each step is executed in sequence. If any of the steps returns a failing result, that result is immediately returned from #steps. Otherwise, #steps wraps the value returned by a block in a Cuprum result.
169 170 171 172 173 174 175 176 177 |
# File 'lib/cuprum/steps.rb', line 169 def steps(&block) raise ArgumentError, 'no block given' unless block_given? result = catch(:cuprum_failed_step) { block.call } return result if result.respond_to?(:to_cuprum_result) success(result) end |