Class: Brainstem::DSL::Configuration

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/brainstem/dsl/configuration.rb

Defined Under Namespace

Classes: InheritableAppendSet

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent_configuration = nil) ⇒ Configuration

Returns a new configuration object.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/brainstem/dsl/configuration.rb', line 15

def initialize(parent_configuration = nil)
  @parent_configuration  = parent_configuration || ActiveSupport::HashWithIndifferentAccess.new
  @storage               = ActiveSupport::HashWithIndifferentAccess.new

  #
  # Nonheritable keys are a bit peculiar: they make the lookup for a key
  # specified as nonheritable to return no result when it falls back to
  # the parent configuration.
  #
  # These keys themselves are inheritable; in this way, a class that
  # descends from another will keep the same behaviour as its superclass
  # without necessarily having the same data. Or to put it another way,
  # if you have specified that 'title' is not inheritable in a
  # superclass's configuration, that is a property of that class, and
  # descendent classes should behave the same way.
  #
  # It is also unlikely that subclasses will modify the list of
  # nonheritable keys.
  parent_nh_keys = parent_configuration &&
    parent_configuration.nonheritable_keys
  @nonheritable_keys = InheritableAppendSet.new(parent_nh_keys)
end

Instance Attribute Details

#nonheritable_keysObject

Returns the value of attribute nonheritable_keys.



86
87
88
# File 'lib/brainstem/dsl/configuration.rb', line 86

def nonheritable_keys
  @nonheritable_keys
end

Instance Method Details

#[](key) ⇒ Object



38
39
40
# File 'lib/brainstem/dsl/configuration.rb', line 38

def [](key)
  get!(key)
end

#[]=(key, value) ⇒ Object



42
43
44
45
46
47
48
49
50
51
# File 'lib/brainstem/dsl/configuration.rb', line 42

def []=(key, value)
  existing_value = get!(key)
  if existing_value.is_a?(Configuration)
    raise 'You cannot override a nested value'
  elsif existing_value.is_a?(InheritableAppendSet)
    raise 'You cannot override an inheritable array once set'
  else
    @storage[key] = value
  end
end

#array!(key) ⇒ Object



58
59
60
61
# File 'lib/brainstem/dsl/configuration.rb', line 58

def array!(key)
  get!(key)
  @storage[key] ||= InheritableAppendSet.new
end

#eachObject



224
225
226
227
228
# File 'lib/brainstem/dsl/configuration.rb', line 224

def each
  keys.each do |key|
    yield key, get!(key)
  end
end

#fetch(key, default = nil, &block) ⇒ Object

Returns the value for the given key, or if it could not be found:

- Raises a +KeyError+ if not passed a default or a block;
- Returns the default if it is passed a default but no block;
- Calls and returns the block if passed a block but no default;
- Calls the block with the default and returns the block if passed a
    default and a block.


200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/brainstem/dsl/configuration.rb', line 200

def fetch(key, default = nil, &block)
  val = get!(key)
  return val if val

  if default && !block_given?
    default
  elsif block_given?
    default ? block.call(default) : block.call
  else
    raise KeyError
  end
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


214
215
216
217
218
# File 'lib/brainstem/dsl/configuration.rb', line 214

def has_key?(key)
  @storage.has_key?(key) ||
    (@parent_configuration.has_key?(key) &&
     key_inheritable_in_parent?(key))
end

#key_inheritable_in_parent?(*key) ⇒ Boolean

An inversion of key_nonheritable_in_parent. Returns true if the key is not marked as nonheritable in the parent configuration.

Is of arity -1 so it can be easily passed to methods that yield either a key, or a key/value tuple.

Parameters:

  • key (Symbol, String)

    the key to check for heritability.

Returns:

  • (Boolean)


166
167
168
# File 'lib/brainstem/dsl/configuration.rb', line 166

def key_inheritable_in_parent?(*key)
  !key_nonheritable_in_parent?(format_key(key.first))
end

#key_nonheritable_in_parent?(*key) ⇒ Boolean

Returns whether a key is nonheritable in this configuration object’s parent configuration.

Is of arity -1 so it can be easily passed to methods that yield either a key, or a key/value tuple.

Parameters:

  • key (Symbol, String)

    the key to check for nonheritability.

Returns:

  • (Boolean)


152
153
154
# File 'lib/brainstem/dsl/configuration.rb', line 152

def key_nonheritable_in_parent?(*key)
  parent_nonheritable_keys.include?(format_key(key.first))
end

#keysArray

Returns the union of all keys in this configuration plus those that are heritable in the parent.

Returns:

  • (Array)

    keys



117
118
119
120
121
122
123
# File 'lib/brainstem/dsl/configuration.rb', line 117

def keys
  if @parent_configuration.respond_to?(:keys_visible_to_children)
    @parent_configuration.keys_visible_to_children | @storage.keys
  else
    @parent_configuration.keys | @storage.keys
  end
end

#keys_visible_to_childrenArray

Returns the keys in this configuration object that are visible to child configuration objects (i.e. heritable keys).

Returns:

  • (Array)

    keys



95
96
97
# File 'lib/brainstem/dsl/configuration.rb', line 95

def keys_visible_to_children
  keys - nonheritable_keys.to_a
end

#lengthObject



220
221
222
# File 'lib/brainstem/dsl/configuration.rb', line 220

def length
  keys.length
end

#nest!(key) ⇒ Object



53
54
55
56
# File 'lib/brainstem/dsl/configuration.rb', line 53

def nest!(key)
  get!(key)
  @storage[key] ||= Configuration.new
end

#nonheritable!(key) ⇒ Object

Marks a key in the configuration as nonheritable, which means that the key:

  • will appear in the list of keys for this object;

  • will return its value when fetched from this object;

  • will be included in the to_h output from this object;

  • will be included when iterating with #each from this object;

  • will not appear in the list of keys for any child object;

  • will return nil when fetched from any child object;

  • will not be included in the #to_h output from any child object;

  • will not be included when iterating with #each from any child object.

Parameters:

  • key (Symbol, String)

    the key to append to the list of nonheritable keys



80
81
82
83
# File 'lib/brainstem/dsl/configuration.rb', line 80

def nonheritable!(key)
  formatted_key = format_key(key)
  self.nonheritable_keys << formatted_key unless self.nonheritable_keys.include?(formatted_key)
end

#pairs_visible_to_childrenHash

Returns a hash of this object’s storage, less those pairs that are not visible to children.

Returns:

  • (Hash)

    the hash, less nonheritable pairs.



106
107
108
# File 'lib/brainstem/dsl/configuration.rb', line 106

def pairs_visible_to_children
  to_h.select {|k, v| keys_visible_to_children.include?(format_key(k)) }
end

#parent_nonheritable_keysArray<String>

Returns a list of nonheritable keys for the parent configuration, if the parent configuration actually keeps track of it. Otherwise returns an empty array.

Returns:

  • (Array<String>)

    the list of nonheritable keys in the parent configuration.



134
135
136
137
138
139
140
# File 'lib/brainstem/dsl/configuration.rb', line 134

def parent_nonheritable_keys
  if @parent_configuration.respond_to?(:nonheritable_keys)
    @parent_configuration.nonheritable_keys
  else
    []
  end
end

#to_hHash

Returns a hash of this object’s storage merged over the heritable pairs of its parent configurations.

Returns:

  • (Hash)

    the merged hash



177
178
179
180
181
182
183
# File 'lib/brainstem/dsl/configuration.rb', line 177

def to_h
  if @parent_configuration.respond_to?(:pairs_visible_to_children)
    @parent_configuration.pairs_visible_to_children.merge(@storage)
  else
    @parent_configuration.to_h.merge(@storage)
  end
end