Discussion about this post

User's avatar
Alexander Zubkov's avatar

I found "do notation" from dry-monads the best. It uses exceptions under the hood to control flow, every method may accept any amount of arguments and terminate the chain on failure, returned values may be passed to next methods which you need. We had a custom monad implementation on a previous project, but there were many problems which dry-monads solves, otherwise you will have to write that yourself or deal with a partial implementation. So we preferred to add a dependency over our code.

Julik's avatar

If your procedure does not run in a very tight loop, Exceptions for flow control in Ruby are fine - because they replace the Either. If you rescue exceptions according to their class (using matching of some description) you get a very good reproduction of an Either, much better than the approach with tuples of `[:ok, :result] and `[:error, :message]`. One of the unpleasant aspects of those tuples is that nothing prevents you from having a `[:ok, :error_message]` or a `[:error, :result]` creep in (say hello to the Go error handling). So I would do it with exceptions and a reduce - if your pipeline needs to be composable. If it isn't, maybe a straight-ahead `input = do_thing(input)` per line would be even simpler.

```ruby

calls = [

-> (input) { do_thing(input) },

-> (input) { do_another_thing(input) },

-> (input) { do_yet_another_thing(input) },

]

result = calls.inject("hello!") do |input_from_previous, callable|

callable.(input_from_previous)

end

```

4 more comments...

No posts

Ready for more?