Class: Bogo::Stack::Action

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/bogo/stack.rb

Overview

Actions which are run via the stack

Defined Under Namespace

Classes: Arguments

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stack:, callable: nil, &block) ⇒ Action

Create a new action

Parameters:

  • stack (Stack)

    stack associated with this action

  • callable (Object) (defaults to: nil)

    callable item



411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/bogo/stack.rb', line 411

def initialize(stack:, callable: nil, &block)
  super()
  if callable && block
    raise ArgumentError,
      "Expecting callable argument or block, not both"
  end
  c = callable || block
  if c.is_a?(Class)
    if !c.instance_methods.include?(:call)
      raise ArgumentError,
        "Expecting callable but class does not provide `#call'"
    end
  else
    if !c.respond_to?(:call)
      raise ArgumentError,
        "Expecting callable but no callable provided"
    end
  end
  if !stack.is_a?(Stack)
    raise TypeError,
      "Expecting `#{Stack.name}` but received `#{stack.class.name}`"
  end
  @stack = stack
  @callable = c
  @called = false
  @arguments = []
end

Instance Attribute Details

#argumentsArray<Object>, Arguments (readonly)

Returns arguments for callable.

Returns:



404
405
406
# File 'lib/bogo/stack.rb', line 404

def arguments
  @arguments
end

#callableObject (readonly)

Returns callable.

Returns:

  • (Object)

    callable



402
403
404
# File 'lib/bogo/stack.rb', line 402

def callable
  @callable
end

#stackStack (readonly)

Returns parent stack.

Returns:

  • (Stack)

    parent stack



400
401
402
# File 'lib/bogo/stack.rb', line 400

def stack
  @stack
end

Instance Method Details

#call(context: nil) ⇒ Object

Call the action

Parameters:



485
486
487
488
489
490
491
492
493
494
495
# File 'lib/bogo/stack.rb', line 485

def call(context: nil)
  synchronize do
    raise Error::PreparedError,
      "Cannot call action, not prepared" if !arguments.frozen?
    raise Error::CalledError,
      "Action has already been called" if called?
    @called = true
    callable.call(*arguments.list, **arguments.named)
  end
  stack.call(context: context)
end

#called?Boolean

Returns action has been called.

Returns:

  • (Boolean)

    action has been called



478
479
480
# File 'lib/bogo/stack.rb', line 478

def called?
  !!@called
end

#prepareObject

Prepare the action to be called



452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/bogo/stack.rb', line 452

def prepare
  synchronize do
    if @arguments.frozen?
      raise Error::PreparedError,
        "Action has already been prepared"
    end
    if callable.is_a?(Class)
      @callable = callable.new
    end
    if !callable.respond_to?(:call)
      raise ArgumentError,
        "Given callable does not respond to `#call'"
    end
    m = callable.method(:call)
    @arguments = Arguments.load(callable: m, arguments: @arguments)
    if m.parameters.any?{ |p| [:key, :keyreq].include?(p.first) && p.last == :context }
      @arguments.named[:context] = stack.context if !@arguments.key?(:context)
    end
    @arguments.validate!(m)
    @callable.freeze
    @arguments.freeze
  end
  self
end

#with(*args) ⇒ Object

Arguments to pass to callable



440
441
442
443
444
445
446
447
448
449
# File 'lib/bogo/stack.rb', line 440

def with(*args)
  synchronize do
    if @arguments.frozen?
      raise Error::PreparedError,
        "Cannot set arguments after action has been prepared"
    end
    @arguments = args
  end
  self
end