Skip to content

Instantly share code, notes, and snippets.

@scottwb
Created November 30, 2009 00:49
Show Gist options
  • Save scottwb/245172 to your computer and use it in GitHub Desktop.
Save scottwb/245172 to your computer and use it in GitHub Desktop.
Ruby Config Hierarchy Class
#!/usr/bin/env ruby
# This file demonstrates a simple experiment to make a hierarchy of config classes
# where each class can simply define a hash of config values which augment/override
# those of it's parent class. Each class uses class methods to access the config
# values by name. In addition to the config hash, each class can define custom
# class methods that combine/format config values, even if those values are actually
# defined in an ancestor or descendant class.
class BaseConfig
########################################
# Config This Class
########################################
def initialize
@values = {
:base_url => "http://www.example.com",
:path => "api"
}
end
########################################
# Common Base Class Helpers
########################################
def self.url
"#{self.base_url}/#{self.path}"
end
########################################
# Base Class Magic
########################################
class << self
attr_accessor :instance
end
def method_missing(method, *params)
msym = method.to_sym
if @values.has_key?(msym)
return @values[msym]
else
self.class.ancestors[1].send(method, *params)
end
end
def self.method_missing(method, *params)
self.instance ||= self.new
self.instance.send(method, *params)
end
end
######################################################################
# Subclasses (these just config their values)
######################################################################
class ServerConfig < BaseConfig
def initialize
@values = {
:port => "9090"
}
end
end
class LocalConfig < BaseConfig
def initialize
@values = {
:state => "Washington"
}
end
end
# Note two levels of class inheritance and the crazy way of writing
# it to try to move everything out of sight but the config values.
class MicroConfig < LocalConfig; def initialize; @values = {
:city => "Kirkland",
# Note it can override a parent's config.
:path => "KirkApi"
}; end; end
# Test to prove it.
puts "#{BaseConfig.url}"
puts "#{ServerConfig.url}/#{ServerConfig.port}"
puts "#{LocalConfig.url}/#{LocalConfig.state}"
puts "#{MicroConfig.url}/#{MicroConfig.state}/#{MicroConfig.city}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment