Class: BetterSettings

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/better_settings.rb,
lib/better_settings/version.rb

Overview

Public: Rewrite of BetterSettings to enforce fail-fast and immutability, and avoid extending a core class like Hash which can be problematic.

Defined Under Namespace

Classes: InvalidSettingKey, MissingSetting

Constant Summary collapse

VALID_SETTING_NAME =
/^\w+$/
RESERVED_METHODS =
%w[
  settings
  root_settings
]
VERSION =
'1.0.2'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash, parent:) ⇒ BetterSettings

Public: Initializes a new settings object from a Hash or compatible object.



24
25
26
27
28
29
30
# File 'lib/better_settings.rb', line 24

def initialize(hash, parent:)
  @settings = hash.to_h.freeze
  @parent = parent

  # Create a getter method for each setting.
  @settings.each { |key, value| create_accessor(key, value) }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name) ⇒ Object

Internal: Display explicit errors for typos and missing settings.

Raises:



38
39
40
# File 'lib/better_settings.rb', line 38

def method_missing(name, *)
  raise MissingSetting, "Missing setting '#{ name }' in #{ @parent }"
end

Instance Attribute Details

#settingsObject (readonly)

Returns the value of attribute settings.



19
20
21
# File 'lib/better_settings.rb', line 19

def settings
  @settings
end

Class Method Details

.source(file_name, namespace: false, optional: false) ⇒ Object

Public: Loads a file as settings (merges it with any previously loaded settings).



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/better_settings.rb', line 81

def source(file_name, namespace: false, optional: false)
  return if !File.exist?(file_name) && optional

  # Load the specified yaml file and instantiate a Settings object.
  settings = new(yaml_to_hash(file_name), parent: file_name)

  # Take one of the settings keys if one is specified.
  settings = settings.public_send(namespace) if namespace

  # Merge settings if a source had previously been specified.
  @root_settings = @root_settings ? @root_settings.merge(settings) : settings

  # Allow to call any settings methods directly on the class.
  singleton_class.extend(Forwardable)
  singleton_class.def_delegators :root_settings, *@root_settings.settings.keys
end

Instance Method Details

#merge(other_settings) ⇒ Object

Internal: Returns a new Better Settings instance that combines the settings.



33
34
35
# File 'lib/better_settings.rb', line 33

def merge(other_settings)
  self.class.new(deep_merge(@settings, other_settings.to_h), parent: @parent)
end