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 #chainrelated 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.