class ContextProvider

A ContextProvider allows data to be passed down the call stack in a explicit way while avoiding having to pass parameters just so it can be used by a nested function.

@example

context = ContextProvider.new

context.provide("bar") do
  context.get #=> "bar"
end

Constants

VERSION

Public Class Methods

new() click to toggle source
# File lib/context_provider.rb, line 24
def initialize
  @provided = Concurrent::ThreadLocalVar.new
  @provide_call_stack = Concurrent::ThreadLocalVar.new
end

Public Instance Methods

dangerously_set_provided_value(value) click to toggle source

Sets provided value. Doesn't perform any checks. Doesn't clean up (see dangerously_unset_provided_value). Should only be used as a last resort.

@param [Object] value

# File lib/context_provider.rb, line 92
def dangerously_set_provided_value(value)
  set_provided_value(value)
end
dangerously_unset_provided_value() click to toggle source

Unsets provided value. Doesn't perform any checks. Meant to be used in conjunction with dangerously_set_provided_value. Should only be used as a last resort.

# File lib/context_provider.rb, line 100
def dangerously_unset_provided_value
  unset_provided_value
end
get() click to toggle source

Gets value from provided by the context.

@raises [ContextNotProvidedError] if no value has been provided

@return [Object] provided value

# File lib/context_provider.rb, line 54
def get
  unless value_provided?
    raise ContextNotProvidedError,
          'Unable to get context value as it has not been defined!'
  end

  @provided.value
end
provide(value, &block) click to toggle source

Provided value that can be accessed using get inside the nested block.

@raise [ContextAlreadyDefinedError] if context has already been provide

@param [Object] value Value to be passed down the stack @param [Proc] block Block where provided value is going to be available.

# File lib/context_provider.rb, line 35
def provide(value, &block)
  if value_provided?
    raise ContextAlreadyProvidedError,
          'Failed to provide context because it has already been provided!'
  end

  begin
    set_provided_value(value)
    block.call
  ensure
    unset_provided_value
  end
end
value_provided?() click to toggle source

Returns true when value has been provided (inside a provide block) false otherwise.

@return [Boolean]

# File lib/context_provider.rb, line 67
def value_provided?
  @provide_call_stack.value != nil
end
where_provide_was_called() click to toggle source

Returns the callstack for where provide was called.

@raise [ContextNotProvidedError] if no value has been provided

@return [Array] callstack for where provide was called

# File lib/context_provider.rb, line 76
def where_provide_was_called
  unless value_provided?
    raise ContextNotProvidedError,
          'Unable to get the provide callstack because context has not been ' \
          'provided!'
  end

  @provide_call_stack.value
end

Private Instance Methods

set_provided_value(value) click to toggle source

rubocop:disable Naming/AccessorMethodName

# File lib/context_provider.rb, line 107
def set_provided_value(value)
  @provide_call_stack.value = caller(2)
  @provided.value = value
end
unset_provided_value() click to toggle source

rubocop:enable Naming/AccessorMethodName

# File lib/context_provider.rb, line 113
def unset_provided_value
  @provided.value = nil
  @provide_call_stack.value = nil
end