class ActiveOperation::Base

Attributes

error[RW]
output[RW]

Public Class Methods

call(*args) click to toggle source
# File lib/active_operation/base.rb, line 54
def call(*args)
  perform(*args)
end
from_proc(execute) click to toggle source
# File lib/active_operation/base.rb, line 23
def from_proc(execute)
  Class.new(self) do
    positional_arguments = []
    keyword_arguments = []

    execute.parameters.each do |type, name|
      case type
      when :req
        input name, type: :positional, required: true
        positional_arguments << name
      when :keyreq
        input name, type: :keyword, required: true
        keyword_arguments << name
      else
        raise ArgumentError, "Argument type not supported: #{type}"
      end
    end

    define_method(:execute) do
      args = positional_arguments.map { |name| self[name] }
      opts = keyword_arguments.map { |name| [name, self[name]] }.to_h

      if opts.empty?
        execute.call(*args)
      else
        execute.call(*args, **opts)
      end
    end
  end
end
inputs() click to toggle source
# File lib/active_operation/base.rb, line 58
def inputs
  []
end
new(*args) click to toggle source
Calls superclass method
# File lib/active_operation/base.rb, line 130
def initialize(*args)
  arity = self.class.inputs.count(&:positional?)
  arguments = args.shift(arity)
  attributes = args.last.kind_of?(Hash) ? args.pop : {}

  raise ArgumentError, "wrong number of arguments #{arguments.length + args.length} for #{arity}" unless args.empty?

  self.class.inputs.select(&:positional?).each_with_index do |input, index|
    attributes[input.name] = arguments[index]
  end

  super(attributes)
end
perform(*args) click to toggle source
# File lib/active_operation/base.rb, line 19
def perform(*args)
  new(*args).call
end
to_proc() click to toggle source
# File lib/active_operation/base.rb, line 62
def to_proc
  ->(*args) {
    perform(*args)
  }
end

Protected Class Methods

after(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 92
def after(*args, &callback)
  set_callback(:execute, :after, *args, &callback)
end
around(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 88
def around(*args, &callback)
  set_callback(:execute, :around, *args, &callback)
end
before(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 84
def before(*args, &callback)
  set_callback(:execute, :before, *args, &callback)
end
error(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 96
def error(*args, &callback)
  set_callback(:error, :after, *args, &callback)
end
halted(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 104
def halted(*args, &callback)
  set_callback(:halted, :after, *args, &callback)
end
input(name, type: :positional, **configuration) click to toggle source
# File lib/active_operation/base.rb, line 70
def input(name, type: :positional, **configuration)
  property(name, type: type, **configuration)
end
property(name, type: :keyword, **configuration) click to toggle source
Calls superclass method
# File lib/active_operation/base.rb, line 74
def property(name, type: :keyword,  **configuration)
  @inputs ||= []

  if type == :positional
    @inputs << ActiveOperation::Input.new(type: :positional, property: super(name, required: true, **configuration))
  else
    @inputs << ActiveOperation::Input.new(type: :keyword, property: super(name, **configuration))
  end
end
succeeded(*args, &callback) click to toggle source
# File lib/active_operation/base.rb, line 100
def succeeded(*args, &callback)
  set_callback(:succeeded, :after, *args, &callback)
end

Private Class Methods

inherited(subclass) click to toggle source
Calls superclass method
# File lib/active_operation/base.rb, line 115
def inherited(subclass)
  super

  subclass.define_singleton_method(:inputs) do
    superclass.inputs + Array(@inputs)
  end
end
method_added(method) click to toggle source
Calls superclass method
# File lib/active_operation/base.rb, line 110
def method_added(method)
  super
  protected method if method == :execute
end

Public Instance Methods

call() click to toggle source
# File lib/active_operation/base.rb, line 164
def call
  perform
end
completed?() click to toggle source
# File lib/active_operation/base.rb, line 181
def completed?
  halted? || succeeded?
end
halted?() click to toggle source
# File lib/active_operation/base.rb, line 173
def halted?
  state == :halted
end
perform() click to toggle source
# File lib/active_operation/base.rb, line 144
def perform
  run_callbacks :execute do
    catch(:abort) do
      next if completed?
      @output = execute
      self.state = :succeeded
    end
  end

  run_callbacks :halted if halted?
  run_callbacks :succeeded if succeeded?

  self.output
rescue => error
  self.state = :failed
  self.error = error
  run_callbacks :error
  raise
end
succeeded?() click to toggle source
# File lib/active_operation/base.rb, line 177
def succeeded?
  state == :succeeded
end

Protected Instance Methods

execute() click to toggle source
# File lib/active_operation/base.rb, line 187
def execute
  raise NotImplementedError
end
halt(*args) click to toggle source
# File lib/active_operation/base.rb, line 191
def halt(*args)
  raise ActiveOperation::AlreadyCompletedError if completed?

  self.state = :halted
  @output = args.length > 1 ? args : args.first
  throw :abort
end
succeed(*args) click to toggle source
# File lib/active_operation/base.rb, line 199
def succeed(*args)
  raise ActiveOperation::AlreadyCompletedError if completed?

  self.state = :succeeded
  @output = args.length > 1 ? args : args.first
  throw :abort
end