Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Simple Hash extension to make working with nested hashes (e.g. for configuration) easier and less error-prone.

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 test
Octocat-spinner-32 .travis.yml
Octocat-spinner-32 Gemfile
Octocat-spinner-32 Gemfile.lock
Octocat-spinner-32 MIT-LICENSE
Octocat-spinner-32 README.md
Octocat-spinner-32 Rakefile
Octocat-spinner-32 hashr.gemspec
README.md

Build Status

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.

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

Usage

Directly use Hashr instances like this:

config = Hashr.new('foo' => { 'bar' => 'bar' })

config.foo?     # => true
config.foo      # => { :bar => 'bar' }

config.foo.bar? # => true
config.foo.bar  # => 'bar'

config.foo.bar = 'bar!'
config.foo.bar # => 'bar!'

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:

config = Hashr.new
config.foo? # => false
config.foo  # => nil

You can make Hashr raise an IndexError though like this:

Hashr.raise_missing_keys = true
config = Hashr.new
config.foo? # => false
config.foo  # => raises an IndexError "Key :foo is not defined."

You can also anonymously overwrite core Hash methods like this:

config = Hashr.new(:count => 3) do
  def count
    self[:count]
  end
end
config.count # => 3

And you can anonymously provide defaults like this:

data     = { :foo => 'foo' }
defaults = { :bar => 'bar' }
config   = Hashr.new(data, defaults)
config.foo # => 'foo'
config.bar # => 'bar'

But you can obvioulsy also derive a custom class to define defaults and overwrite core Hash methods like this:

class Config < Hashr
  define :foo => { :bar => 'bar' }

  def count
    self[:count]
  end
end

config = Config.new
config.foo.bar # => 'bar'

Include modules to nested hashes like this:

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:

class Config < Hashr
  extend Hashr::EnvDefaults

  self.env_namespace = 'foo'

  define :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

Other libraries

You also might want to check out OpenStruct and Hashie.

  • OpenStruct does less but comes as a Ruby standard library.
  • Hashie has a bunch of support classes (like Mash, Dash, Trash) which all support different features that you might need.

License

MIT License

Something went wrong with that request. Please try again.