ChainIt
Description
This provides the tool which is implementation of railway-oriented programming concept itself (Read more on this here).
Ideally suited for executing task sequences that should be immediately interrupted when any subsequen task fails.
Usage
Everything comes down to chaining subsequent #chain
method calls to a ChainIt
object instance.
The gem supports design-by-contract programming concept - assuming every block related to #chain
have to return both #value
and #failure?
aware object.We reccomend using Struct for that purpouse.
Result = Struct.new(:success, :value) do
def failure?
!success
end
end
Examples
# Basic flow explanation
success = ->(value) { Result.new(true, value) }
ChainIt.new.
chain { success.call 2 }. #=> The subsequent chain will be triggered
chain { |num| success.call(num * 2) }. #=> We can pass the previous block evaluation as the block argument
chain { |num| success.call(num * 2) }.
result.
value #=> 8
# Working with #skip_next
ChainIt.new.
chain { success.call 2 }.
skip_next { |num| num == 2 }. #=> The next chain will be skipped conditionally since block returns true
chain { success.call 8 }.
chain { |num| success.call(num * 2) }. #=> The block argument is the last executed #chain value
result.
value #=> 4
# Dealing with a failure
failure = ->(value) { Result.new(false, value) }
ChainIt.new.
chain { success.call 2 }.
chain { failure.call 0 }. #=> All later #chain calls will be skipped
chain { success.call 4 }.
result.
value #=> 0
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/spark-solutions/chain_it.
License
The gem is available as open source under the terms of the MIT License.