Class: Setting

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/setting.rb,
lib/mc-settings/version.rb

Defined Under Namespace

Classes: AlreadyLoaded, FileError, NotFound

Constant Summary collapse

VERSION =
'0.2.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSetting

Instance Methods



101
102
103
# File 'lib/setting.rb', line 101

def initialize
  @available_settings = {}
end

Instance Attribute Details

#available_settingsObject (readonly)

Returns the value of attribute available_settings.



30
31
32
# File 'lib/setting.rb', line 30

def available_settings
  @available_settings
end

Class Method Details

.[](value) ⇒ Object

In [] invocation syntax, we return settings value ‘as is’ without Hash conversions.

For example, if the YML data is: tax:

default: 0.0
california: 7.5

Then calling Setting returns

{ 'default' => "0.0", 'california' => "7.5"}


89
90
91
# File 'lib/setting.rb', line 89

def [](value)
  instance.value_for(value)
end

.available_settingsObject

DEPRECATED: Please use method accessors instead.



94
95
96
# File 'lib/setting.rb', line 94

def available_settings
  instance.available_settings
end

.load(**args) ⇒ Object

This method can be called only once.

Parameter hash looks like this:

{  :files => [ "file1.yml", "file2.yml", ...],
   :path  => "/var/www/apps/my-app/current/config/settings",
   :local => true }

If :local => true is set, we will load all *.yml files under :path/local directory after all files in :files have been loaded. “Local” settings thus take precedence by design. See README for more details.

Raises:



45
46
47
48
49
# File 'lib/setting.rb', line 45

def load(**args)
  raise AlreadyLoaded, 'Settings already loaded' if instance.loaded?

  instance.load(**args)
end

.method_missing(method, *args) ⇒ Object

In Method invocation syntax we collapse Hash values and return a single value if ‘default’ is found among keys or Hash has only one key/value pair.

For example, if the YML data is: tax:

default: 0.0
california: 7.5

Then calling Setting.tax returns “0.0”“

This is the preferred method of using settings class.



68
69
70
71
72
# File 'lib/setting.rb', line 68

def method_missing(method, *args)
  instance.value_for(method, args) do |v, args|
    instance.collapse_hashes(v, args)
  end
end

.reload(**args) ⇒ Object



51
52
53
# File 'lib/setting.rb', line 51

def reload(**args)
  instance.load(**args)
end

.respond_to_missing?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/setting.rb', line 74

def respond_to_missing?
  true
end

Instance Method Details

#collapse_hashes(v, args) ⇒ Object

This method performs collapsing of the Hash settings values if the Hash contains ‘default’ value, or just 1 element.



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/setting.rb', line 140

def collapse_hashes(v, args)
  out = if v.is_a?(Hash)
          if args.empty?
            if v.key?("default")
              v['default'].nil? ? "" : v['default']
            elsif v.keys.size == 1
              v.values.first
            else
              v
            end
          else
            v[args.shift.to_s]
          end
        else
          v
        end
  if out.is_a?(Hash) && !args.empty?
    collapse_hashes(out, args)
  elsif out.is_a?(Hash) && out.key?('default')
    out['default']
  else
    out
  end
end

#key?(key) ⇒ Boolean Also known as: has_key?

Parameters:

  • key (Object)

Returns:

  • (Boolean)


106
107
108
109
# File 'lib/setting.rb', line 106

def key?(key)
  @available_settings.key?(key) ||
    (key[-1, 1] == '?' && @available_settings.key?(key.chop))
end

#load(**params) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/setting.rb', line 169

def load(**params)
  # reset settings hash
  @available_settings = {}
  @loaded             = false

  files = []
  path  = params[:path] || Dir.pwd
  params[:files].each do |file|
    files << File.join(path, file)
  end
  if params[:local]
    files << Dir.glob(File.join(path, 'local', '*.yml')).sort
  end

  files.flatten.each do |file|
    if File.exist?(file)
      @available_settings.recursive_merge! load_file(file)
    end
  rescue StandardError => e
    raise FileError, "Error parsing file #{file}, with: #{e.message}"
  end

  @loaded = true
  @available_settings
end

#loaded?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/setting.rb', line 165

def loaded?
  @loaded
end

#value_for(key, args = []) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/setting.rb', line 113

def value_for(key, args = [])
  name = key.to_s
  unless key?(name)
    raise NotFound, "#{name} was not found"
  end

  bool = false
  if name[-1, 1] == '?'
    name.chop!
    bool = true
  end

  v = @available_settings[name]
  if block_given?
    v = yield(v, args)
  end

  if v.is_a?(Integer) && bool
    v.to_i > 0
  else
    v
  end
end