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.
As not hard to guess, all is about chaining subsequent #chain method calls to a ChainIt instance.
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 recommend using Struct:
Result = Struct.new(:success, :value) do
def failure?
!success
end
end#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 success of failure.
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.
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 #=> 4failure = ->(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 #=> 0ChainIt.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 #=> 2ChainIt.new.
chain { raise StandardError.new }. #=> StandardError: StandardError
result.
valueChainIt.new(auto_exception_handling: true).
chain { raise StandardError.new }.
result. #=> <StandardError: StandardError>
value #=> <StandardError: StandardError>All the contributions are really welcome on GitHub at https://github.com/tier-tools/chainit according to the open-source spirit.
The gem is available as open source under the terms of the MIT License.