Module: Assistant::ExecuteCallbacks

Included in:
Service
Defined in:
lib/assistant/execute_callbacks.rb

Overview

Class-level DSL for registering before_execute / after_execute / around_execute hooks on Assistant::Service subclasses (M-S1).

Mixed into Service.singleton_class so the DSL is available at class definition time. Hooks are stored as UnboundMethods on private anonymous Modules so we can bind self to the service instance and still pass a block (the continuation) into around_execute hooks.

Hooks are inherited at subclass-definition time: a subclass receives a duplicate of each registered hook array. Adding more hooks to the subclass does not affect the parent, and vice-versa.

See docs/v1/02-features.md M-S1 and docs/v1/01-api-surface.md.

Constant Summary collapse

HOOK_TYPES =

The exhaustive set of hook types this module manages.

Returns:

  • (Array<Symbol>)
%i[before_execute after_execute around_execute].freeze

Instance Method Summary collapse

Instance Method Details

#after_execute {|execute_result| ... } ⇒ Array<UnboundMethod>

Register a block to run after #execute returns. self inside the block is the service instance; the execute result is passed as the single positional argument.

Yield Parameters:

  • execute_result (Object)

    return value of #execute

Returns:

Raises:

  • (ArgumentError)

    when no block is given



55
56
57
58
59
# File 'lib/assistant/execute_callbacks.rb', line 55

def after_execute(&block)
  raise ArgumentError, 'after_execute requires a block' unless block

  after_execute_hooks << build_hook(block)
end

#after_execute_hooksArray<UnboundMethod>

Returns hooks registered via #after_execute, in declaration order.

Returns:

  • (Array<UnboundMethod>)

    hooks registered via #after_execute, in declaration order



27
28
29
# File 'lib/assistant/execute_callbacks.rb', line 27

def after_execute_hooks
  @after_execute_hooks ||= []
end

#around_execute {|blk| ... } ⇒ Array<UnboundMethod>

Register a block that wraps #execute. self inside the block is the service instance; the &blk block argument yields to the inner stack (the next around hook, or #execute for the innermost layer). Declaration order wraps: the first declared hook is the outermost layer.

Yields:

  • runs in the context of the service instance, wrapping the inner stack

Yield Parameters:

  • blk (Proc)

    the continuation; call yield (or blk.call) to invoke the inner layer

Returns:

Raises:

  • (ArgumentError)

    when no block is given



71
72
73
74
75
# File 'lib/assistant/execute_callbacks.rb', line 71

def around_execute(&block)
  raise ArgumentError, 'around_execute requires a block' unless block

  around_execute_hooks << build_hook(block)
end

#around_execute_hooksArray<UnboundMethod>

Returns hooks registered via #around_execute, in declaration order.

Returns:

  • (Array<UnboundMethod>)

    hooks registered via #around_execute, in declaration order



32
33
34
# File 'lib/assistant/execute_callbacks.rb', line 32

def around_execute_hooks
  @around_execute_hooks ||= []
end

#before_execute { ... } ⇒ Array<UnboundMethod>

Register a block to run after validation and before #execute. self inside the block is the service instance.

Yields:

  • runs in the context of the service instance after validation, before #execute

Returns:

Raises:

  • (ArgumentError)

    when no block is given



42
43
44
45
46
# File 'lib/assistant/execute_callbacks.rb', line 42

def before_execute(&block)
  raise ArgumentError, 'before_execute requires a block' unless block

  before_execute_hooks << build_hook(block)
end

#before_execute_hooksArray<UnboundMethod>

Returns hooks registered via #before_execute, in declaration order.

Returns:

  • (Array<UnboundMethod>)

    hooks registered via #before_execute, in declaration order



22
23
24
# File 'lib/assistant/execute_callbacks.rb', line 22

def before_execute_hooks
  @before_execute_hooks ||= []
end

#inherited(subclass) ⇒ void

This method returns an undefined value.

Snapshot parent hooks into the subclass at definition time. The snapshot is a dup so the subclass owns its own array and further additions on either side never bleed across the hierarchy.

Parameters:

  • subclass (Class)

    freshly defined subclass



83
84
85
86
87
88
# File 'lib/assistant/execute_callbacks.rb', line 83

def inherited(subclass)
  super
  subclass.instance_variable_set(:@before_execute_hooks, before_execute_hooks.dup)
  subclass.instance_variable_set(:@after_execute_hooks,  after_execute_hooks.dup)
  subclass.instance_variable_set(:@around_execute_hooks, around_execute_hooks.dup)
end