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.

Parameters:

  • name (Symbol) (defaults to: :default)

    The name of the scope to retrieve (defaults to :default)

Returns:

  • (Array)

    A duplicate of the 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.

Parameters:

  • scope_frame (Object)

    The scope frame to push

  • name (Symbol) (defaults to: :default)

    The name of the scope to use (defaults to :default)

Yields:

  • (void)

    The block to execute within the scope

Returns:

  • (Object)

    The result of the block execution



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.

Parameters:

  • name (Symbol) (defaults to: :default)

    The name of the scope to retrieve (defaults to :default)

Returns:

  • (Array)

    The scope stack for the given name



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.

Parameters:

  • name (Symbol) (defaults to: :default)

    The name of the scope to use (defaults to :default)

Returns:

  • (self)

    Returns self to enable method chaining



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.

Parameters:

  • scope_frame (Object)

    The object to push onto the stack

  • name (Symbol) (defaults to: :default)

    The name of the scope to use (defaults to :default)

Returns:

  • (self)

    Returns self to enable method chaining



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.

Parameters:

  • name (Symbol) (defaults to: :default)

    The name of the scope to use (defaults to :default)

Yields:

  • (frame)

    Yields each frame from top to bottom

Returns:

  • (Enumerator)

    If no block is given, returns an enumerator



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.

Parameters:

  • name (Symbol) (defaults to: :default)

    The name of the scope to use (defaults to :default)

Returns:

  • (Object, nil)

    The top element of the stack or nil if empty



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

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