Explicitly state a failure with Ruby Result Monad
Be clear about the result of your process

The Result monad is a useful tool provided by dry-monad gem. It can be used for many different purposes, but what I consider the main one is the ability to pass the information about status & result of a process, be that failure or success.
And for this specific reason, Result has two types of constructors in its arsenal: Success and Failure. Obviously Success indicates that whole process was successfully completed, Failure on the other hand, can help us to inform a caller about failure, at which step it failed and what might be the reason for it.
It’s important to mention that by using it, output of the process is well known and expected. There is no surprise that Success is in fact success, right? It’s clear and explicit. When you state Failure or Success in your code, it might help your colleague or another maintainer to easy pinpoint places in code where something is expected to go wrong.
With usage of Result, you can portion your code as separate procedures, run them step by step and make it clear where next process starts and ends.
Let’s assume that there is a service, that has to do some specific job, but does not return anything of importance. It’s purpose is to calculate a value and update a field in database. From the caller’s perspective, there are 2 separate steps that can fail. First would be calculating the value, second would be updating database field. With typical response, we would not be able to track which step has failed. That’s where Result monad comes in.
You can send Failure objects that contain symbol that describes what kind of problem has occurred. Knowing what exactly went wrong, we can act accordingly.
class ImportantService
include Dry::Monads::Result::Mixin def self.call(x, y)
value = ValueCalculator.call(x, y)
return Failure(:value_is_empty) if value.nil? result = FieldUpdater.call(value)
return Failure(:failed_to_save) unless result Success(value)
end
end
This code can be further improved using do notation that dry-monad gem provides as well. But this is a topic for another post.
