Module: Philiprehberger::StateBag

Defined in:
lib/philiprehberger/state_bag.rb,
lib/philiprehberger/state_bag/version.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
'0.6.0'

Class Method Summary collapse

Class Method Details

.clearvoid

This method returns an undefined value.

Clear all entries from the thread-local state bag



57
58
59
# File 'lib/philiprehberger/state_bag.rb', line 57

def self.clear
  store.clear
end

.delete(key) ⇒ Object

Remove a key from the state bag

Parameters:

  • key (Symbol, String)

    the key to remove

Returns:

  • (Object)

    the removed value or nil



108
109
110
# File 'lib/philiprehberger/state_bag.rb', line 108

def self.delete(key)
  store.delete(key)
end

.dig(*keys) ⇒ Object?

Dig into nested hash-valued entries using a sequence of keys

Mirrors Ruby’s Hash#dig. Looks up the first key in the thread-local store, then calls :dig on the resulting value with the remaining keys. Returns nil on any missing key. Raises ArgumentError when no keys are given, and TypeError when an intermediate value does not respond to :dig (matching Hash#dig behavior).

Parameters:

  • keys (Array<Symbol, String>)

    the key path to traverse

Returns:

  • (Object, nil)

    the nested value, or nil on any miss

Raises:

  • (ArgumentError)

    if no keys are given



98
99
100
101
102
# File 'lib/philiprehberger/state_bag.rb', line 98

def self.dig(*keys)
  raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)' if keys.empty?

  store.dig(*keys)
end

.each {|key, value| ... } ⇒ Enumerator, Hash

Iterate over key-value pairs in the state bag

Yields:

  • (key, value)

    each key-value pair

Returns:

  • (Enumerator)

    when no block is given

  • (Hash)

    the state bag snapshot when a block is given



179
180
181
182
183
# File 'lib/philiprehberger/state_bag.rb', line 179

def self.each(&block)
  return store.dup.each_pair unless block

  store.dup.each_pair(&block)
end

.empty?Boolean

Check whether the state bag is empty.

Returns:

  • (Boolean)


130
131
132
# File 'lib/philiprehberger/state_bag.rb', line 130

def self.empty?
  store.empty?
end

.fetch(key, default = UNSET) {|key| ... } ⇒ Object

Fetch a value from the state bag with strict key checking

Parameters:

  • key (Symbol, String)

    the key to retrieve

  • default (Object) (defaults to: UNSET)

    optional default if key is not found

Yields:

  • (key)

    optional block called when key is not found

Returns:

  • (Object)

    the stored value, default, or block result

Raises:

  • (KeyError)

    if key not found and no default or block given



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/philiprehberger/state_bag.rb', line 75

def self.fetch(key, default = UNSET, &block)
  if store.key?(key)
    store[key]
  elsif block
    block.call(key)
  elsif default != UNSET
    default
  else
    raise KeyError, "key not found: #{key.inspect}"
  end
end

.get(key, default = nil) ⇒ Object

Get a value from the thread-local state bag

Parameters:

  • key (Symbol, String)

    the key to retrieve

  • default (Object) (defaults to: nil)

    optional default if key is not found

Returns:

  • (Object)

    the stored value or default



26
27
28
# File 'lib/philiprehberger/state_bag.rb', line 26

def self.get(key, default = nil)
  store.fetch(key, default)
end

.key?(key) ⇒ Boolean

Check if a key exists in the state bag

Parameters:

  • key (Symbol, String)

    the key to check

Returns:

  • (Boolean)

    true if the key exists



116
117
118
# File 'lib/philiprehberger/state_bag.rb', line 116

def self.key?(key)
  store.key?(key)
end

.keysArray

Return all keys in the state bag.

Returns:

  • (Array)


137
138
139
# File 'lib/philiprehberger/state_bag.rb', line 137

def self.keys
  store.keys
end

.merge(**entries) ⇒ Hash

Bulk-set multiple entries in the state bag

Parameters:

  • entries (Hash)

    key-value pairs to write

Returns:

  • (Hash)

    snapshot of the state bag after the merge



152
153
154
155
# File 'lib/philiprehberger/state_bag.rb', line 152

def self.merge(**entries)
  entries.each { |k, v| store[k] = v }
  store.dup
end

.replace(hash) ⇒ Hash

Replace the entire state bag with the given hash

Parameters:

  • hash (Hash)

    the new state

Returns:

  • (Hash)

    snapshot of the state bag after the replacement



161
162
163
164
# File 'lib/philiprehberger/state_bag.rb', line 161

def self.replace(hash)
  store.replace(hash.dup)
  store.dup
end

.set(key, val) ⇒ Object

Set a value in the thread-local state bag

Parameters:

  • key (Symbol, String)

    the key to set

  • val (Object)

    the value to store

Returns:

  • (Object)

    the stored value



17
18
19
# File 'lib/philiprehberger/state_bag.rb', line 17

def self.set(key, val)
  store[key] = val
end

.sizeInteger

Return the number of entries in the state bag.

Returns:

  • (Integer)


123
124
125
# File 'lib/philiprehberger/state_bag.rb', line 123

def self.size
  store.size
end

.slice(*keys) ⇒ Hash

Return a subset of the state bag containing only the given keys

Parameters:

  • keys (Array)

    keys to extract

Returns:

  • (Hash)

    subset of the state (keys not present are omitted)



170
171
172
# File 'lib/philiprehberger/state_bag.rb', line 170

def self.slice(*keys)
  store.slice(*keys)
end

.to_hHash

Return a snapshot of the current state as a hash

Returns:

  • (Hash)

    copy of the current state



64
65
66
# File 'lib/philiprehberger/state_bag.rb', line 64

def self.to_h
  store.dup
end

.valuesArray

Return all values in the state bag.

Returns:

  • (Array)


144
145
146
# File 'lib/philiprehberger/state_bag.rb', line 144

def self.values
  store.values
end

.with(**overrides) { ... } ⇒ Object

Execute a block with temporary state, restoring previous values after

Parameters:

  • overrides (Hash)

    key-value pairs to set during the block

Yields:

  • the block to execute with the temporary state

Returns:

  • (Object)

    the return value of the block



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/philiprehberger/state_bag.rb', line 35

def self.with(**overrides, &block)
  previous = {}
  missing = []

  overrides.each do |k, v|
    if store.key?(k)
      previous[k] = store[k]
    else
      missing << k
    end
    store[k] = v
  end

  block.call
ensure
  previous.each { |k, v| store[k] = v }
  missing.each { |k| store.delete(k) }
end