Discussion about this post

User's avatar
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

```

Expand full comment
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:

```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

```

Expand full comment
1 more comment...

No posts