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.



84
85
86
# File 'lib/brainstem/dsl/configuration.rb', line 84

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



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

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.


190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/brainstem/dsl/configuration.rb', line 190

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)


203
204
205
206
207
# File 'lib/brainstem/dsl/configuration.rb', line 203

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)


158
159
160
# File 'lib/brainstem/dsl/configuration.rb', line 158

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)


145
146
147
# File 'lib/brainstem/dsl/configuration.rb', line 145

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



112
113
114
115
116
117
118
# File 'lib/brainstem/dsl/configuration.rb', line 112

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



92
93
94
# File 'lib/brainstem/dsl/configuration.rb', line 92

def keys_visible_to_children
  keys - nonheritable_keys.to_a
end

#lengthObject



209
210
211
# File 'lib/brainstem/dsl/configuration.rb', line 209

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



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

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.



102
103
104
# File 'lib/brainstem/dsl/configuration.rb', line 102

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.



128
129
130
131
132
133
134
# File 'lib/brainstem/dsl/configuration.rb', line 128

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



168
169
170
171
172
173
174
# File 'lib/brainstem/dsl/configuration.rb', line 168

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