DEV Community

olistik
olistik

Posted on

3 3

Playing with execution flows in Ruby

Let's define a simple Result class:

class Result
  def initialize(success: true, data: nil); @success = success; @data = data; end
  def success?; @success == true; end
  def error?; !success?; end
  def data; @data; end
  def self.success(data = nil); new(data: data); end
  def self.error(data = nil); new(success: false, data: data); end
end
Enter fullscreen mode Exit fullscreen mode

and then a Flow class:

class Flow
  attr_accessor :tasks, :result

  def initialize(tasks: [])
    self.tasks = tasks
    self.result = nil
  end

  def step(task)
    self.tasks << task
  end

  def call
    tasks.each do |task|
      begin
        self.data = task.call
        self.result = Result.success(data) unless result.kind_of?(Result)
      rescue => exception
        self.result = Result.error(exception)
      end
      return result if result.error?
    end

    result
  end
end
Enter fullscreen mode Exit fullscreen mode

We can now do some interesting things such as:

flow = Flow.new
flow.step -> { puts '#1' }
flow.step -> { puts '#2'; 3 * 3 }
flow.step -> { puts '#3 (error)'; raise 'foo' }
flow.step -> { puts '#4' }
result = flow.call

result.error? # => true
result.data # => #<RuntimeError: foo>
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay