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.