ChainIt
Gain full control over what is going in your code!
What exactly is ChainIt
?
It's the Ruby implementation of a railway-oriented programming concept. read more
The gem makes it super easy to control complex operations flow - the next step will happen only if the previous one was successful.
Ideally suited for handling task sequences that should be interrupted as soon as any subsequent task fails.
How should I use ChainIt
?
As not hard to guess, alll is about chaining subsequent #chain
method calls to a ChainIt
instance.
Prerequisites
The gem supports design-by-contract programming concept assuming ChainIt
will be used together with both #value
and #failure?
aware object that have to be returned by every #chain
related block. It is used to consider the operation successful or failed.
We reccomend using Struct
:
Result = Struct.new(:success, :value) do
def failure?
!success
end
end
Interface explanation
#initialize
- Initiates the operation. Auto exception handling mode is configurable here. (see examples section)
#chain
- Performs the code in its related block and memorizes the internal result value. This is done only when the state of the operation allows it.
#skip_next
- Skips the next #chain
call when it's block evaluates to true
.
#result
- The result of the operation representing succes of failure.
ChainIt
modes
auto_exception_handling
- default false
- Decide if any StandardError
exception should be rescued from any #chain
call. If so the rescued exception will be memorized as operation result object.
Examples
Success path
success = ->(value) { Result.new(true, value) }
ChainIt.new.
chain { success.call 2 }.
chain { |num| success.call(num * 2) }. # The operation result is passed as block argument if used.
result. #=> <struct Result success=true, value=4>
value #=> 4
Failure path
failure = ->(value) { Result.new(false, value) }
ChainIt.new.
chain { success.call 2 }.
chain { failure.call 0 }. # All later steps calls will be skipped.
chain { success.call 4 }.
result. #=> <struct Result success=false, value=0>
value #=> 0
Working with #skip_next
ChainIt.new.
chain { success.call 2 }.
skip_next { |num| num == 2 }. # The next chain will be skipped as the block evaluates to true.
chain { success.call 8 }.
result. #=> <struct Result success=true, value=2>
value #=> 2
With auto_exception_handling
mode disabled
ChainIt.new.
chain { raise StandardError.new }. #=> StandardError: StandardError
result.
value
With auto_exception_handling
mode enabled
ChainIt.new(auto_exception_handling: true).
chain { raise StandardError.new }.
result. #=> <StandardError: StandardError>
value #=> <StandardError: StandardError>
Develop ChainIt
All the contributions are really welcome on GitHub at https://github.com/tier-tools/chainit according to the open-source spirit.
ChainIt
License
The gem is available as open source under the terms of the MIT License.