Skip to content

Instantly share code, notes, and snippets.

@woahdae
Created March 3, 2014 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save woahdae/9319735 to your computer and use it in GitHub Desktop.
Save woahdae/9319735 to your computer and use it in GitHub Desktop.
settings.rb
module MyApp
def self.settings
Settings.instance
end
class MyApp::Settings < BasicObject
# so we can reference classes w/o appending '::'
def self.const_missing(name)
::Object.const_get(name)
end
include Singleton
def initialize
config_dir = "#{File.expand_path(File.dirname(__FILE__))}/../config"
settings = YAML.load(ERB.new(IO.read("#{config_dir}/settings.yml")).result)
host_settings = YAML.load(ERB.new(IO.read("#{config_dir}/settings.host.yml")).result)
hostname = Socket.gethostname
# load host specific config
if (host_settings.has_key?(Rails.env) && host_settings[Rails.env].has_key?(hostname))
settings[Rails.env] ||= {}
settings[Rails.env].deep_merge!(host_settings[Rails.env][hostname])
end
if File.exists?("#{config_dir}/settings.yml.local")
settings.deep_merge!(YAML.load(ERB.new(
IO.read("#{config_dir}/settings.yml.local")).result))
end
@values = HashObj.from_hash(override_with_env(
settings['defaults'].deep_merge(settings[Rails.env])))
end
def override_with_env(settings, path = [])
settings.each_pair do |key, value|
if value.is_a?(Hash)
override_with_env(value, (path.dup << key.upcase))
else
settings[key] = ENV[(path.dup << key.upcase).join('_')] || value
end
end
end
private :override_with_env
def [](key)
@values[key]
end
def []=(key, value)
@values[key] = value
end
def method_missing(key, value = nil)
if key.to_s[-1] == '='
@values[key.to_s[0...-1]] = value
else
@values[key]
end
end
class HashObj < BasicObject
def initialize(*args)
@data = ::HashWithIndifferentAccess.new(*args)
end
def self.from_hash(hash)
hobj = new
hash.each_pair do |key, value|
hobj[key] = value
end
hobj
end
def []=(key, value)
if value.is_a?(::Hash) && !value.is_a?(HashObj)
# See HashWithIndifferentAccess for where these methods come from
current = @data[key]
if current && current.is_a?(::Hash)
current = current.deep_merge(value)
end
@data.regular_writer(@data.send(:convert_key, key),
HashObj.from_hash(current || value))
else
@data[key] = value
end
end
def [](key)
@data[key]
end
def inspect
@data.inspect
end
def keys
@data.keys
end
def values
@data.values
end
def to_s
@data.to_s
end
def __data__
@data
end
def has_key?(key)
@data.has_key?(key)
end
def deep_merge(other)
@data.deep_merge(other)
end
def is_a?(klass)
[::Hash, ::HashWithIndifferentAccess, HashObj].include?(klass)
end
def try(method, *args)
__send__(method, *args)
end
def method_missing(key, value = nil)
if key.to_s[-1] == '='
@data[key.to_s[0...-1]] = value
else
@data[key]
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment