Created
November 30, 2009 00:49
Ruby Config Hierarchy Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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