Module: Simple::Service

Defined in:
lib/simple/service.rb,
lib/simple/service/action.rb,
lib/simple/service/action.rb,
lib/simple/service/errors.rb,
lib/simple/service/context.rb,
lib/simple/service/context.rb,
lib/simple/service/version.rb

Overview

The Simple::Service module.

To mark a target module as a service module one must include the Simple::Service module into the target module.

This serves as a marker that this module is actually intended to be used as a service.

Defined Under Namespace

Modules: ClassMethods, GemHelper Classes: Action, ArgumentError, Context, ContextMissingError, ContextReadOnlyError, ExtraArguments, MissingArguments, NoSuchAction

Constant Summary collapse

VERSION =
GemHelper.version "simple-service"

Class Method Summary collapse

Class Method Details

.action(service, name) ⇒ Object

returns the action with the given name.



41
42
43
44
45
46
# File 'lib/simple/service.rb', line 41

def self.action(service, name)
  actions = self.actions(service)
  actions[name] || begin
    raise ::Simple::Service::NoSuchAction.new(service, name)
  end
end

.actions(service) ⇒ Object

returns a Hash with all actions in the service module



34
35
36
37
38
# File 'lib/simple/service.rb', line 34

def self.actions(service)
  verify_service!(service)

  service.__simple_service_actions__
end

.contextObject

Returns the current context.



3
4
5
# File 'lib/simple/service/context.rb', line 3

def self.context
  Thread.current[:"Simple::Service.context"]
end

.included(klass) ⇒ Object

:nodoc:



19
20
21
# File 'lib/simple/service.rb', line 19

def self.included(klass) # :nodoc:
  klass.extend ClassMethods
end

.invoke(service, name, *args, **named_args) ⇒ Object

invokes an action with a given name in a service with arguments and params.

You cannot call this method if the context is not set.

When calling #invoke using positional arguments they will be matched against positional arguments of the invoked method - but they will not be matched against named arguments.

When there are not enough positional arguments to match the number of required positional arguments of the method we raise an ArgumentError.

When there are more positional arguments provided than the number accepted by the method we raise an ArgumentError.

Entries in the named_args Hash that are not defined in the action itself are ignored.



63
64
65
66
67
# File 'lib/simple/service.rb', line 63

def self.invoke(service, name, *args, **named_args)
  raise ContextMissingError, "Need to set context before calling ::Simple::Service.invoke" unless context

  action(service, name).invoke(*args, **named_args)
end

.invoke2(service, name, args: {}, flags: {}) ⇒ Object

invokes an action with a given name in a service with a Hash of arguments.

You cannot call this method if the context is not set.



72
73
74
75
76
77
# File 'lib/simple/service.rb', line 72

def self.invoke2(service, name, args: {}, flags: {})
  args.each { |key, _| expect! key => Symbol }
  raise ContextMissingError, "Need to set context before calling ::Simple::Service.invoke" unless context

  action(service, name).invoke2(args: args, flags: flags)
end

.service?(service) ⇒ Boolean

returns true if the passed in object is a service module.

Returns:

  • (Boolean)


24
25
26
# File 'lib/simple/service.rb', line 24

def self.service?(service)
  service.is_a?(Module) && service.include?(self)
end

.verify_service!(service) ⇒ Object

:nodoc:

Raises:

  • (::ArgumentError)


28
29
30
31
# File 'lib/simple/service.rb', line 28

def self.verify_service!(service) # :nodoc:
  raise ::ArgumentError, "#{service.inspect} must be a Simple::Service, but is not even a Module" unless service.is_a?(Module)
  raise ::ArgumentError, "#{service.inspect} must be a Simple::Service, did you 'include Simple::Service'" unless service?(service)
end

.with_context(ctx = nil, &block) ⇒ Object

yields a block with a given context, and restores the previous context object afterwards.



9
10
11
12
13
14
15
16
17
18
# File 'lib/simple/service/context.rb', line 9

def self.with_context(ctx = nil, &block)
  old_ctx = Thread.current[:"Simple::Service.context"]
  new_ctx = old_ctx ? old_ctx.merge(ctx) : Context.new(ctx)

  Thread.current[:"Simple::Service.context"] = new_ctx

  block.call
ensure
  Thread.current[:"Simple::Service.context"] = old_ctx
end