• Stars
    star
    190
  • Rank 202,997 (Top 5 %)
  • Language
    Ruby
  • Created almost 13 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Yet another hash/struct-like configuration object for Ruby

confstruct Build Status Dependency Status

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.

Usage

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"}

Other Features

Deferred evaluation

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/Pop configurations

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!

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"

lists

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"]

Notes

  • Confstruct will attempt to use ordered hashes internally when available.
    • In Ruby 1.9 and above, this is automatic.
    • In Rubies earlier than 1.9, Confstruct will try to require and use ActiveSupport::OrderedHash, falling back to a regular Hash if necessary. The class/instance method ordered? can be used to determine if the hash is ordered or not.
  • In order to support struct access, all hash keys are converted to symbols, and are accessible both as strings and symbols (like a HashWithIndifferentAccess). In other words, config['foo'] and config[:foo] refer to the same value.

Release History

  • v0.1.0 - Initial release
  • v0.2.0 - Add fallback value to HashWithStructAccess#lookup!, native support for Rails I18n.
  • v0.2.1 - Initialize properly from a nested hash with string (non-symbol) keys
  • v0.2.2 - Fix ArgumentError on #respond_to?(sym, true)
  • v0.2.3 - Don't evaluate Deferreds during #inspect
  • v0.2.4 - Fix deferreds under Ruby 1.9.x
  • v0.2.5 - #14 #configure loses nested hashes somehow
  • v0.2.6 - Fix test scoping issue under Ruby 2.1.0+
  • v0.2.7 - Remove ActiveSupport for Ruby >= 1.9
  • v1.0.0 - [YANKED] Refactor to use Hashie instead of reinventing all the Hash access stuff
  • v1.0.1 - Switch back to symbolized keys internally
  • v1.1.0 - Include support for Hashie 4, Rspec 3, and Ruby 2.7

Contributing to confstruct

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
  • Fork the project
  • Start a feature/bugfix branch
  • Commit and push until you are happy with your contribution
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

License

confstruct is released under the MIT License.

More Repositories

1

equivalent-xml

Easy equivalency tests for Nokogiri and Oga XML
Ruby
94
star
2

rack-conneg

Content negotiation middleware for Rack-based web applcations
Ruby
32
star
3

jquery-elastic

Fork of Jan Jarfalk's excellent jquery-elastic plugin
JavaScript
12
star
4

openils-mapper

EDIFACT<->JSON middleware for the Evergreen Open Source ILS
Ruby
7
star
5

availability-server

Thin availability layer for OSU Library's OPAC
Ruby
7
star
6

handle

Classes and methods for dealing with Handle System servers and handles.
Ruby
6
star
7

contentdm-ruby

Ruby module to pull data and metadata out of CONTENTdm repositories
Ruby
4
star
8

dot-properties

Read and write Java-style .properties files with minimal intrusiveness
Ruby
4
star
9

sesame-ruby

A simple Ruby wrapper around the CANDY HOUSE Sesame API to control Sesame Bluetooth and Internet-connected locks.
Ruby
4
star
10

docker-stack

Generators, rake tasks, and support code for running Rails on top of Dockerized services.
Ruby
4
star
11

nwda-ead

Archivists Toolkit EAD Converter for NWDA
Ruby
3
star
12

rails-irc-log

IRC Logging bot in a Rails framework
Ruby
3
star
13

FedoraFS

Mounts a Fedora Commons repository as a filesystem
Ruby
3
star
14

jquery-ajaxQ

Rate-limited, queued AJAX requests for jQuery 1.5+
JavaScript
3
star
15

rsolr-client-cert

Client certificate authentication for RSolr
Ruby
2
star
16

arooo

Moderator tools for vBulletin-hosted Werewolf games
JavaScript
2
star
17

two-way-grid

jqGrid<->tab-delimited textarea
JavaScript
2
star
18

bad-elf

Elixir
1
star
19

parkit

A single URL stasher
Ruby
1
star
20

githooks

Custom github service hooks
Ruby
1
star
21

mod-cons

NOTE: This project has been deprecated in favor of the similar (but saner) confstruct.
Ruby
1
star
22

remote-checkin

Barcode emailing for courier returns
JavaScript
1
star
23

cahdmaker

Ruby
1
star
24

bundler-rcov-bug

Minimal example for Bundler+RCov bug report
Ruby
1
star
25

diebold-graph

Time-series graph for code4lib's diebold-o-tron voting mechanism
Ruby
1
star
26

webhook-deploy

Run a capistrano deploy from a github webhook
Ruby
1
star
27

at-svg

Experimenting with SVG, Canvas, jQuery, and Raphaël.js all at the same time
JavaScript
1
star
28

family-oral-history

TypeScript
1
star