Class: Bogo::Stack
Overview
Simple call stack implementation
Defined Under Namespace
Classes: Action, Context, Entry, Error, Hooks
Instance Attribute Summary collapse
-
#actions ⇒ Array<Action>
readonly
List of actions in the stack.
-
#context ⇒ Context
readonly
Context for the stack.
-
#hooks ⇒ Hooks
readonly
Hooks for stack.
-
#parallel ⇒ Boolean
readonly
Actions run in parallel.
Instance Method Summary collapse
-
#call(context: nil) ⇒ Object
Execute the next action in the stack.
-
#initialize ⇒ Stack
constructor
Create a new stack.
-
#insert(at:, callable:, adjust: 0) ⇒ self
(also: #insert_at)
Insert item into stack at given index.
-
#insert_after(idx: nil, callable: nil, &block) ⇒ self
Insert item after given index.
-
#insert_before(idx: nil, callable: nil, &block) ⇒ self
Insert item before given index.
-
#parallelize! ⇒ self
Enable parallel execution of stack actions.
-
#pop ⇒ Action?
Remove last action from the stack.
-
#prepare ⇒ self
Prepare the stack to be called.
-
#prepared? ⇒ TrueClass, FalseClass
Stack is prepared for execution.
-
#push(callable = nil, &block) ⇒ Action
Push a new callable action onto the end of the stack.
-
#remove(idx = nil) {|Array<Action>| ... } ⇒ Action, NilClass
Remove item from the stack.
-
#shift ⇒ Action?
Remove first action from the stack.
-
#size ⇒ Integer
Number of actions in stack.
-
#started? ⇒ TrueClass, FalseClass
Stack has started execution.
-
#unshift(callable = nil, &block) ⇒ Action
Unshift a new callable action onto the start of the stack.
Constructor Details
Instance Attribute Details
#actions ⇒ Array<Action> (readonly)
Returns list of actions in the stack.
501 502 503 |
# File 'lib/bogo/stack.rb', line 501 def actions @actions end |
#context ⇒ Context (readonly)
Returns context for the stack.
503 504 505 |
# File 'lib/bogo/stack.rb', line 503 def context @context end |
#hooks ⇒ Hooks (readonly)
Returns hooks for stack.
505 506 507 |
# File 'lib/bogo/stack.rb', line 505 def hooks @hooks end |
#parallel ⇒ Boolean (readonly)
Returns actions run in parallel.
507 508 509 |
# File 'lib/bogo/stack.rb', line 507 def parallel @parallel end |
Instance Method Details
#call(context: nil) ⇒ Object
Execute the next action in the stack
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'lib/bogo/stack.rb', line 685 def call(context: nil) synchronize do be_prepared! if context be_unstarted! @context = context.for(self) end if @parallel acts = @actions.dup @actions = [] acts.each do |action| Thread.new { action.call(context: @context) } end else action = pop action.call(context: context) if action end end end |
#insert(at:, callable:, adjust: 0) ⇒ self Also known as: insert_at
Insert item into stack at given index
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/bogo/stack.rb', line 588 def insert(at:, callable:, adjust: 0) synchronize do be_unprepared! idx = yield stack if idx.nil? && block_given? if !idx.is_a?(Integer) && !idx.is_a?(Action) raise ArgumentError, "Expecting `Integer` or `#{Action.name}` but received `#{idx.class.name}`" end callable = Action.new(stack: self, callable: callable) if !callable.is_a?(Action) @actions = actions.dup @actions.insert(idx + adjust, callable) @actions.freeze end self end |
#insert_after(idx: nil, callable: nil, &block) ⇒ self
Insert item after given index
624 625 626 |
# File 'lib/bogo/stack.rb', line 624 def insert_after(idx: nil, callable: nil, &block) insert(idx: idx, callable: callable, adjust: -1, &block) end |
#insert_before(idx: nil, callable: nil, &block) ⇒ self
Insert item before given index
613 614 615 |
# File 'lib/bogo/stack.rb', line 613 def insert_before(idx: nil, callable: nil, &block) insert(idx: idx, callable: callable, adjust: 1, &block) end |
#parallelize! ⇒ self
Enable parallel execution of stack actions
525 526 527 528 529 530 |
# File 'lib/bogo/stack.rb', line 525 def parallelize! synchronize do be_unprepared! @parallel = true end end |
#pop ⇒ Action?
Remove last action from the stack
631 632 633 634 635 636 637 638 |
# File 'lib/bogo/stack.rb', line 631 def pop synchronize do @actions = actions.dup action = actions.pop @actions.freeze action end end |
#prepare ⇒ self
Prepare the stack to be called
671 672 673 674 675 676 677 678 679 680 |
# File 'lib/bogo/stack.rb', line 671 def prepare synchronize do be_unprepared! @actions = hooks.apply! @actions.freeze actions.each(&:prepare) @prepared = true end self end |
#prepared? ⇒ TrueClass, FalseClass
Returns stack is prepared for execution.
664 665 666 |
# File 'lib/bogo/stack.rb', line 664 def prepared? @prepared end |
#push(callable = nil, &block) ⇒ Action
Push a new callable action onto the end of the stack
537 538 539 540 541 542 543 544 |
# File 'lib/bogo/stack.rb', line 537 def push(callable=nil, &block) synchronize do be_unprepared! act = Action.new(stack: self, callable: callable, &block) @actions = ([act]+ actions).freeze act end end |
#remove(idx = nil) {|Array<Action>| ... } ⇒ Action, NilClass
Remove item from the stack
566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/bogo/stack.rb', line 566 def remove(idx=nil) synchronize do be_unprepared! idx = yield stack if idx.nil? && block_given? if !idx.is_a?(Integer) && !idx.is_a?(Action) raise ArgumentError, "Expecting `Integer` or `#{Action.name}` but received `#{idx.class}`" end @actions = actions.dup entry = @actions.delete(idx) @actions.freeze entry end end |
#shift ⇒ Action?
Remove first action from the stack
643 644 645 646 647 648 649 650 651 |
# File 'lib/bogo/stack.rb', line 643 def shift synchronize do be_unprepared! @actions = actions.dup action = actions.shift @actions.freeze action end end |
#size ⇒ Integer
Returns number of actions in stack.
654 655 656 |
# File 'lib/bogo/stack.rb', line 654 def size actions.size end |
#started? ⇒ TrueClass, FalseClass
Returns stack has started execution.
659 660 661 |
# File 'lib/bogo/stack.rb', line 659 def started? @started end |
#unshift(callable = nil, &block) ⇒ Action
Unshift a new callable action onto the start of the stack
551 552 553 554 555 556 557 558 |
# File 'lib/bogo/stack.rb', line 551 def unshift(callable=nil, &block) synchronize do be_unprepared! act = Action.new(stack: self, callable: callable, &block) @actions = (actions + [act]).freeze act end end |