Cuprum

An opinionated implementation of the Command pattern for Ruby applications. Cuprum wraps your business logic in a consistent, object-oriented interface and features status and error management, composability and control flow management.

Class: Cuprum::Operation

Parent Namespace
Cuprum
Inherited Classes
Cuprum::Command > Object
Included Modules
Cuprum::Operation::Mixin
Defined In
lib/cuprum/operation.rb

Table Of Contents

Overview

Functional object with syntactic sugar for tracking the last result.

An Operation is like a Command, but with two key differences. First, an Operation retains a reference to the result object from the most recent time the operation was called and delegates the methods defined by Cuprum::Result to the most recent result. This allows a called Operation to replace a Cuprum::Result in any code that expects or returns a result. Second, the #call method returns the operation instance, rather than the result itself.

These two features allow developers to simplify logic around calling and using the results of operations, and reduce the need for boilerplate code (particularly when using an operation as part of an existing framework, such as inside of an asynchronous worker or a Rails controller action).

Like a Command, an Operation can be defined directly by passing an implementation block to the constructor or by creating a subclass that overwrites the #process method.

Examples

def create
  operation = CreateBookOperation.new.call(book_params)

  if operation.success?
    redirect_to(operation.value)
  else
    @book = operation.value

    render :new
  end
end

See Also

Back To Top

Defined Under Namespace

Modules
Mixin

Back To Top

Class Methods

.subclass(*class_arguments, **class_keywords, &block) => Class

Inherited From
Cuprum::Command

Creates a subclass with partially applied constructor parameters.

Parameters

Yields

Returns

Back To Top

Constructor

#initialize(&implementation) => Command

Inherited From
Cuprum::Command

Returns a new instance of Cuprum::Command.

Yields

Yield Parameters

Yield Returns

Returns

Back To Top

Instance Attributes

#result => Cuprum::Result (readonly)

Inherited From
Cuprum::Operation::Mixin

Returns

Back To Top

Instance Methods

#arity => Integer

Inherited From
Cuprum::Processing

Returns an indication of the number of arguments accepted by #call.

If the method takes a fixed number N of arguments, returns N. If the method takes a variable number of arguments, returns -N-1, where N is the number of required arguments. Keyword arguments will be considered as a single additional argument, that argument being mandatory if any keyword argument is mandatory.

Returns

See Also

#call(*arguments, **keywords, &block) => Cuprum::Operation

Calls the command implementation and stores the result.

Parameters

Yields

Returns

See Also

#called? => Boolean

Returns

#curry(*arguments, **keywords, &block) => Cuprum::Currying::CurriedCommand

Inherited From
Cuprum::Currying

Returns a CurriedCommand that wraps this command with pre-set arguments.

When the curried command is called, the predefined arguments and/or keywords will be combined with the arguments passed to #call.

The original command is unchanged.

Parameters

Returns

See Also

#error => Object

Returns

#failure? => Boolean

Returns

#process(*arguments, **keywords, &block) => Cuprum::Result, Object

Inherited From
Cuprum::Command

Note: This is a private method.

The implementation of the command.

Whereas the #call method provides the public interface for calling a command, the #process method defines the actual implementation. This method should not be called directly.

When the command is called via #call, the parameters are passed to #process. 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.

Parameters

Yields

Returns

#reset! => Object

Clears the reference to the most recent call of the operation, if any. This allows the result and any referenced data to be garbage collected. Use this method to clear any instance variables or state internal to the operation (an operation should never have external state apart from the last result).

If the operation cannot be run more than once, this method should raise an error.

#result => Cuprum::Result

Returns

#status => Symbol, nil

Inherited From
Cuprum::Operation::Mixin

Returns

#step => Object

Inherited From
Cuprum::Steps

Executes the block and returns the value, or halts on a failure.

The #step method is used to evaluate a sequence of processes, and to fail fast and halt processing if any of the steps returns a failing result. Each invocation of #step should be wrapped in a #steps block, or used inside the #process method of a Command.

If the object returned by the block is a Cuprum result or compatible object (such as a called operation), the value is converted to a Cuprum result via the #to_cuprum_result method. Otherwise, the object is returned directly from #step.

If the returned object is a passing result, the #value of the result is returned by #step.

If the returned object is a failing result, then #step will throw :cuprum_failed_result and the failing result. This is caught by the #steps block, and halts execution of any subsequent steps.

Examples

Calling a Step

# The #do_something method returns the string 'some value'.
step { do_something() } #=> 'some value'

value = step { do_something() }
value #=> 'some value'

Calling a Step with a Passing Result

# The #do_something_else method returns a Cuprum result with a value
# of 'another value'.
step { do_something_else() } #=> 'another value'

# The result is passing, so the value is extracted and returned.
value = step { do_something_else() }
value #=> 'another value'

Calling a Step with a Failing Result

# The #do_something_wrong method returns a failing Cuprum result.
step { do_something_wrong() } # Throws the :cuprum_failed_step symbol.

Yields

Returns

Raises

#steps(&block) => Cuprum::Result

Inherited From
Cuprum::Steps

Returns the first failing #step result, or the final result if none fail.

The #steps method is used to wrap a series of #step calls. Each step is executed in sequence. If any of the steps returns a failing result, that result is immediately returned from #steps. Otherwise, #steps wraps the value returned by a block in a Cuprum result.

Examples

With A Passing Step

result = steps do
  step { success('some value') }
end
result.class    #=> Cuprum::Result
result.success? #=> true
result.value    #=> 'some value'

With A Failing Step

result = steps do
  step { failure('something went wrong') }
end
result.class    #=> Cuprum::Result
result.success? #=> false
result.error    #=> 'something went wrong'

With Multiple Steps

result = steps do
  # This step is passing, so execution continues on to the next step.
  step { success('first step') }

  # This step is failing, so execution halts and returns this result.
  step { failure('second step') }

  # This step will never be called.
  step { success('third step') }
end
result.class    #=> Cuprum::Result
result.success? #=> false
result.error    #=> 'second step'

Yields

Yield Returns

Returns

Raises

#success? => Boolean

Returns

#to_cuprum_result => Cuprum::Result

Returns

#to_proc => Proc

Inherited From
Cuprum::Command

Wraps the command in a proc.

Calling the proc will call the command with the given arguments, keywords, and block.

Returns

#value => Object

Returns

Back To Top


Back to Documentation | Reference | Cuprum