Module: Tins::Scope

Included in:
DynamicScope
Defined in:
lib/tins/dslkit.rb

Overview

A module that provides thread-local stack-based scoping functionality.

This module implements a context management system where each thread maintains its own isolated scope stacks. It’s particularly useful for tracking nested contexts in multi-threaded applications.

Examples:

Basic stack operations

Scope.scope_push("context1")
Scope.scope_push("context2")
Scope.scope_top  # => "context2"
Scope.scope_pop  # => "context2"
Scope.scope_top  # => "context1"

Block-based context management

Scope.scope_block("request_context") do
  # Within this block, "request_context" is active
end
# Automatically cleaned up when block exits

Nested scope blocks

Scope.scope_block("outer_context") do
  Scope.scope_block("inner_context") do
    Scope.scope_top  # => "inner_context"
  end
  Scope.scope_top  # => "outer_context"
end
Scope.scope_top  # => nil (empty stack)

Multiple named scopes

Scope.scope_push("frame1", :database)
Scope.scope_push("frame2", :database)
Scope.scope_get(:database)  # => ["frame1", "frame2"]

Instance Method Summary collapse

Instance Method Details

#scope(name = :default) ⇒ Array

Returns a copy of the specified scope stack.



1030
1031
1032
# File 'lib/tins/dslkit.rb', line 1030

def scope(name = :default)
  scope_get(name).dup
end

#scope_block(scope_frame, name = :default) {|void| ... } ⇒ Object

Executes a block within the context of a scope frame.

Automatically pushes the scope frame before yielding and pops it after the block completes, even if an exception occurs.

Yields:

  • (void)

    The block to execute within the scope



1011
1012
1013
1014
1015
1016
# File 'lib/tins/dslkit.rb', line 1011

def scope_block(scope_frame, name = :default)
  scope_push(scope_frame, name)
  yield
ensure
  scope_pop(name)
end

#scope_get(name = :default) ⇒ Array

Retrieves or initializes the specified scope stack.



1022
1023
1024
# File 'lib/tins/dslkit.rb', line 1022

def scope_get(name = :default)
  Thread.current[name] ||= []
end

#scope_pop(name = :default) ⇒ self

Pops a scope frame from the top of the specified scope stack.

If the scope becomes empty after popping, it is automatically removed from Thread.current to prevent memory leaks.



979
980
981
982
983
# File 'lib/tins/dslkit.rb', line 979

def scope_pop(name = :default)
  scope_get(name).pop
  scope_get(name).empty? and Thread.current[name] = nil
  self
end

#scope_push(scope_frame, name = :default) ⇒ self

Pushes a scope frame onto the top of the specified scope stack.



967
968
969
970
# File 'lib/tins/dslkit.rb', line 967

def scope_push(scope_frame, name = :default)
  scope_get(name).push scope_frame
  self
end

#scope_reverse(name = :default) {|frame| ... } ⇒ Enumerator

Iterates through the specified scope stack in reverse order.

Yields:

  • (frame)

    Yields each frame from top to bottom



998
999
1000
# File 'lib/tins/dslkit.rb', line 998

def scope_reverse(name = :default, &block)
  scope_get(name).reverse_each(&block)
end

#scope_top(name = :default) ⇒ Object?

Returns the top element of the specified scope stack without removing it.



989
990
991
# File 'lib/tins/dslkit.rb', line 989

def scope_top(name = :default)
  scope_get(name).last
end