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
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
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>
Top comments (0)