module Cuprum::Processing

Functional implementation for creating a command object. Cuprum::Processing defines a call method, which performs the implementation defined by process and returns an instance of Cuprum::Result.

@example Defining a command with Cuprum::Processing.

class AdderCommand
  include Cuprum::Processing

  def initialize addend
    @addend = addend
  end

  private

  def process int
    int + addend
  end
end

adder  = AdderCommand.new(2)
result = adder.call(3)
#=> an instance of Cuprum::Result
result.value    #=> 5
result.success? #=> true

@example Defining a command with error handling.

class SquareRootCommand
  include Cuprum::Processing

  private

  def process value
    if value.negative?
      return Cuprum::Result.new(error: 'value cannot be negative')
    end

    Math.sqrt(value)
  end
end

result = SquareRootCommand.new.call(2)
result.value    #=> 1.414
result.success? #=> true
result.failure? #=> false
result.error    #=> nil

result = SquareRootCommand.new.call(-1)
result.value    #=> nil
result.success? #=> false
result.failure? #=> true
result.error    #=> 'value cannot be negative'

@see Cuprum::Command

Public Instance Methods

arity() click to toggle source

Returns a nonnegative integer for commands that take a fixed number of arguments. For commands that take a variable number of arguments, returns -n-1, where n is the number of required arguments.

@return [Integer] The number of arguments.

# File lib/cuprum/processing.rb, line 68
def arity
  method(:process).arity
end
call(*args, **kwargs, &block) click to toggle source

@overload call(*arguments, **keywords, &block)

Executes the command implementation and returns a Cuprum::Result or
compatible object.

Each time #call is invoked, the object performs the following steps:

1. The #process method is called, passing the arguments, keywords, and
   block that were passed to #call.
2. If the value returned by #process is a Cuprum::Result or compatible
   object, that result is directly returned by #call.
3. Otherwise, the value returned by #process will be wrapped in a
   successful result, which will be returned by #call.

@param arguments [Array] Arguments to be passed to the implementation.

@param keywords [Hash] Keywords to be passed to the implementation.

@return [Cuprum::Result] The result object for the command.

@yield If a block argument is given, it will be passed to the
  implementation.
# File lib/cuprum/processing.rb, line 93
def call(*args, **kwargs, &block)
  value =
    if kwargs.empty?
      process(*args, &block)
    else
      process(*args, **kwargs, &block)
    end

  return value.to_cuprum_result if value_is_result?(value)

  build_result(value: value)
end

Private Instance Methods

process(*_args) click to toggle source

@!visibility public @overload process(*arguments, **keywords, &block)

The implementation of the command, to be executed when the #call method
is called. If #process returns a result, that result will be returned by
#call; otherwise, the value returned by #process will be wrapped in a
successful Cuprum::Result object. This method should not be called
directly.

@param arguments [Array] The arguments, if any, passed from #call.

@param keywords [Hash] The keywords, if any, passed from #call.

@yield The block, if any, passed from #call.

@return [Object] the value of the result object to be returned by #call.

@note This is a private method.

# File lib/cuprum/processing.rb, line 125
def process(*_args)
  error = Cuprum::Errors::CommandNotImplemented.new(command: self)

  build_result(error: error)
end
value_is_result?(value) click to toggle source
# File lib/cuprum/processing.rb, line 131
def value_is_result?(value)
  value.respond_to?(:to_cuprum_result)
end