Construct is extensible, persistent, structured configuration for Ruby and humans with text editors. What do I mean? You have a ruby program. Maybe it's a Ramaze app. It needs to store some configuration data. It should be easily serialized to YAML so anyone can edit the file easily. It should support nested structures. It should minimize typing, and make access unambiguous. It should take no effort to create and extend multi-layer configuration with many data types and accessors. Moreover, it should allow you to define a schema for the options that are available, making documentation easy. That's where Construct comes in. gem install construct config = Construct.new Hey, we have a configuration object. Let's describe a web site. Keys are always symbols, but can be accessed via methods just like an OpenStruct. config.name = "Aphyr" config.base_url = "http://aphyr.com" And getting at them is easy, too. config.name => "Aphyr" If the key you want is already a method, just use config#[] and config#[]=. Construct converts strings to symbols for you.. How about a database connection? Those parameters all belong together. config.db = { :user => 'cr', :password => 'some password', } Secretly, Construct converted that hash into another Construct. You can chain methods to easily access nested options. config.db.user => 'cr' Databases need a host. Let's define a host field. config.db.define(:host, :default => '127.0.0.1', :desc => 'The host the database adapter connects to.' ) config.db.host => '127.0.0.1' You can override this, naturally. config.db.host = 'db.aphyr.com' config.db.host => 'db.aphyr.com' The schema is accessible as a hash via #schema, so you can easily pump out configuration docs, HTML forms, whatever. Construct serializes neatly to YAML. Keys are expressed as strings, to save typing and make things look clean. config.to_yaml => --- db: user: cr password: some password name: Aphyr base_url: http://aphyr.com Hey, this is easy! Now let's load that configuration from a string. config = Construct.load yaml Maybe you need to implement extra logic in your config--perhaps you can specify either a db hash as shown above, or a connection string. Just subclass Construct::Construct or define methods directly on the construct. class DBConfig < Construct def db_str self[:db_str] || make_db_string_from_hash(db) end end Defining schemas at the class level, as opposed to creating a Construct instance and operating on its schema is easy. Just use Construct.define to operate on the class schema. When you create an instance of that class, the class schema is used as a default for the instance. class UserConfig < Construct define :state, :desc => "The user's home state" :default => "Oregon" end end conf = UserConfig.new conf.state # => "Oregon" Problem solved. Now get back to having fun instead of worrying about configuration! Contributors ------------ Kyle Kingsbury <aphyr@aphyr.com> Spencer Miles <spencer@vodpod.com>
Project
construct
Extensible, persistent, structured configuration for Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
Pull Requests
Development
Dependencies
Development
~> 1.1
Project Readme