Confstruct is yet another configuration gem. Definable and configurable by hash, struct, or block, confstruct aims to provide the flexibility to do things your way, while keeping things simple and intuitive.
First, either create an empty ConfStruct::Configuration
object:
config = Confstruct::Configuration.new
Or with some default values:
config = Confstruct::Configuration.new({
:project => 'confstruct',
:github => {
:url => 'http://www.github.com/mbklein/confstruct',
:branch => 'master'
}
})
The above can also be done in block form:
config = Confstruct::Configuration.new do
project 'confstruct'
github do
url 'http://www.github.com/mbklein/confstruct'
branch 'master'
end
end
There are many ways to access and configure the resulting config
object...
As a struct...
config.project = 'other-project'
config.github.url = 'http://www.github.com/somefork/other-project'
config.github.branch = 'pre-1.0'
As a block...
config.configure do
project 'other-project'
github.url 'http://www.github.com/somefork/other-project'
github.branch 'pre-1.0'
end
As a hash...
config[:github][:url] = 'http://www.github.com/somefork/other-project'
Or even as a crazy struct/hash hybrid...
config.github[:url] = 'http://www.github.com/somefork/other-project'
config[:github].branch = 'pre-1.0'
Each sub-hash/struct is a configuration object in its own right, and can be
treated as such. (Note the ability to leave the configure
method
off the inner call.)
config.configure do
project 'other-project'
github do
url 'http://www.github.com/somefork/other-project'
branch 'pre-1.0'
end
end
You can even
config.project = 'other-project'
config.github = { :url => 'http://www.github.com/somefork/other-project', :branch => 'pre-1.0' }
The configure method will even perform a deep merge for you if you pass it a hash or hash-like object
(anything that responds to each_pair
)
config.configure({:project => 'other-project', :github => {:url => 'http://www.github.com/somefork/other-project', :branch => 'pre-1.0'}})
Because it's "hashes all the way down," you can store your defaults and/or configurations in YAML files, or in Ruby scripts if you need to evaluate expressions at config-time.
However you do it, the resulting configuration object can be accessed either as a hash or a struct:
config.project
=> "other-project"
config[:project]
=> "other-project"
config.github
=> {:url=>"http://www.github.com/somefork/other-project", :branch=>"pre-1.0"}
config.github.url
=> "http://www.github.com/somefork/other-project"
config.github[:url]
=> "http://www.github.com/somefork/other-project"
config[:github]
=> {:url=>"http://www.github.com/somefork/other-project", :branch=>"pre-1.0"}
Any configuration value of class Confstruct::Deferred
will be evaluated on access, allowing you to
define read-only, dynamic configuration attributes
config.app_name = "iWidgetCloud"
config.msgs.welcome = Confstruct::Deferred.new {|c| "Welcome to #{c.app_name}!"}
config.msgs.welcome
=> "Welcome to iWidgetCloud!"
config.app_name = "Enterprisey-Webscale"
=> "Enterprisey-Webscale"
config.welcome_msg
=> "Welcome to Enterprisey-Webscale"
As a convenience, Confstruct.deferred(&block)
and Confstruct::HashWithStructAccess#deferred!(&block)
will create a Confstruct::Deferred for you, making the following two assignments equivalent to the above:
config.welcome_msg = Confstruct.deferred { |c| "Welcome to #{c.app_name}!" }
config do
welcome_msg deferred! { |c| RestClient::Resource.new(c.url) }
end
push!
and pop!
methods allow you to temporarily override some or all of your configuration values. This can be
useful in spec tests where you need to change values but don't want to worry about messing up tests that depend
on the same global configuration object.
config.github.url
=> "http://www.github.com/mbklein/confstruct"
config.push! { github.url 'http://www.github.com/somefork/other-project' }
=> {:project=>"confstruct", :github=>{:branch=>"master", :url=>"http://www.github.com/somefork/other-project"}}
config.github.url
=> "http://www.github.com/somefork/other-project"
config.pop!
=> {:project=>"confstruct", :github=>{:branch=>"master", :url=>"http://www.github.com/mbklein/confstruct"}}
config.github.url
=> "http://www.github.com/mbklein/confstruct"
lookup!
can be used to look up down a hieararchy without raising on missing values; and/or
to look up with default value.
config = Confstruct::Configuration.new do
project 'confstruct'
github do
url 'http://www.github.com/mbklein/confstruct'
branch 'master'
end
end
config.lookup!("github.url")
=> "http://www.github.com/mbklein/confstruct"
config.lookup!("github.no_key")
=> nil # no raising
config.lookup!("not_there.really.not.there")
=> nil
config.lookup!("github.not_there", "default_value")
=> "default_value"
The pattern add_$key!
can be used to add to or create an array.
config = Confstruct::Configuration.new
config.add_color! "green"
=> ["green"]
config
=> {:color=>["green"]}
config.add_color! "red"
config.color
=> ["green", "red"]
ordered?
can be usedHashWithIndifferentAccess
). In other words, config['foo']confstruct is released under the MIT License.