README.md in hashr-1.0.0 vs README.md in hashr-2.0.0.rc1

- old
+ new

@@ -1,147 +1,109 @@ [![Build Status](https://secure.travis-ci.org/svenfuchs/hashr.png)](http://travis-ci.org/svenfuchs/hashr) # Hashr -Hashr is a very simple and tiny class derived from Ruby's core Hash class which makes using nested hashes for configuration (and other purposes) easier and less repetive and error prone. +Hashr is a very simple and tiny class which makes using nested hashes for +configuration (and other purposes) easier. It supports the following features: * method read and write access * automatic predicate (boolean, i.e. `?`) methods * easy defaults -* easy inclusion of modules into nested hashes -* automatic symbolized keys +* indifferent (strings vs symbols) keys ## Usage Directly use Hashr instances like this: - config = Hashr.new('foo' => { 'bar' => 'bar' }) +```ruby +config = Hashr.new(foo: { bar: 'bar' }) - config.foo? # => true - config.foo # => { :bar => 'bar' } +config.foo? # => true +config.foo # => { bar: 'bar' } - config.foo.bar? # => true - config.foo.bar # => 'bar' +config.foo.bar? # => true +config.foo.bar # => 'bar' - config.foo.bar = 'bar!' - config.foo.bar # => 'bar!' +config.foo.bar = 'bar' +config.foo.bar # => 'bar' - config.foo.baz = 'baz' - config.foo.baz # => 'baz' +config.foo.baz = 'baz' +config.foo.baz # => 'baz' +``` -Be aware that by default missing keys won't raise an exception but instead behave like Hash access: +Hash core methods are not available but assume you mean to look up keys with +the same name: - config = Hashr.new - config.foo? # => false - config.foo # => nil +```ruby +config = Hashr.new(count: 1, key: 'key') +config.count # => 1 +config.key # => 'key' +``` -You can make Hashr raise an `IndexError` though like this: +In order to check a hash stored on a certain key you can convert it to a Ruby +Hash: - Hashr.raise_missing_keys = true - config = Hashr.new - config.foo? # => false - config.foo # => raises an IndexError "Key :foo is not defined." +```ruby +config = Hashr.new(count: 1, key: 'key') +config.to_h.count # => 2 +config.to_h.key # => raises ArgumentError: "wrong number of arguments (0 for 1)" +``` -You can also anonymously overwrite core Hash methods like this: +Missing keys won't raise an exception but instead behave like Hash access: - config = Hashr.new(:count => 3) do - def count - self[:count] - end - end - config.count # => 3 +```ruby +config = Hashr.new +config.foo? # => false +config.foo # => nil +``` -And you can anonymously provide defaults like this: +## Defaults - data = { :foo => 'foo' } - defaults = { :bar => 'bar' } - config = Hashr.new(data, defaults) - config.foo # => 'foo' - config.bar # => 'bar' +Defaults can be defined per class: -But you can obvioulsy also derive a custom class to define defaults and overwrite core Hash methods like this: +```ruby +class Config < Hashr + default boxes: { memory: '1024' } +end - class Config < Hashr - define :foo => { :bar => 'bar' } +config = Config.new +config.boxes.memory # => 1024 +``` - def count - self[:count] - end - end +Or passed to the instance: - config = Config.new - config.foo.bar # => 'bar' +```ruby +data = {} +defaults = { boxes: { memory: '1024' } } -Include modules to nested hashes like this: +config = Hashr.new(data, defaults) +config.boxes.memory # => 1024 +``` - class Config < Hashr - module Boxes - def count - self[:count] # overwrites a Hash method to return the Hash's content here - end - - def names - @names ||= (1..count).map { |num| "box-#{num}" } - end - end - - define :boxes => { :count => 3, :_include => Boxes } - end - - config = Config.new - config.boxes # => { :count => 3 } - config.boxes.count # => 3 - config.boxes.names # => ["box-1", "box-2", "box-3"] - -As overwriting Hash methods for method access to keys is a common pattern there's a short cut to it: - - class Config < Hashr - define :_access => [:count, :key] - end - - config = Config.new(:count => 3, :key => 'key') - config.count # => 3 - config.key # => 'key' - -Both `:_include` and `:_access` can be defined as defaults, i.e. so that they will be used on all nested hashes: - - class Config < Hashr - default :_access => :key - end - - config = Config.new(:key => 'key', :foo => { :key => 'foo.key' }) - config.key # => 'key' - config.foo.key # => 'foo.key' - ## Environment defaults -Hashr includes a simple module that makes it easy to overwrite configuration defaults from environment variables: +Hashr includes a simple module that makes it easy to overwrite configuration +defaults from environment variables: - class Config < Hashr - extend Hashr::EnvDefaults +```ruby +class Config < Hashr + extend Hashr::Env - self.env_namespace = 'foo' + self.env_namespace = 'foo' - define :boxes => { :memory => '1024' } - end + default boxes: { memory: '1024' } +end +``` Now when an environment variable is defined then it will overwrite the default: - ENV['FOO_BOXES_MEMORY'] = '2048' - config = Config.new - config.boxes.memory # => '2048' - -## Running the tests - -You can run the tests as follows: - - # going through bundler - bundle exec rake - - # using just ruby - ruby -rubygems -Ilib:test test/hashr_test.rb +```ruby +ENV['FOO_BOXES_MEMORY'] = '2048' +config = Config.new +config.boxes.memory # => '2048' +``` ## Other libraries You also might want to check out OpenStruct and Hashie.