NAME map.rb SYNOPSIS the awesome ruby container you've always wanted: a string/symbol indifferent ordered hash that works in all rubies maps are bitchin ordered hashes that are both ordered, string/symbol indifferent, and have all sorts of sweetness like recursive conversion, more robust implementation than HashWithIndifferentAccess, support for struct like (map.foo) access, and support for option/keyword access which avoids several nasty classes of errors in many ruby libraries INSTALL gem install map URI http://github.com/ahoward/map DESCRIPTION # maps are always ordered. constructing them in an ordered fashion builds # them that way, although the normal hash contructor is also supported # m = Map[:k, :v, :key, :val] m = Map(:k, :v, :key, :val) m = Map.new(:k, :v, :key, :val) m = Map[[:k, :v], [:key, :val]] m = Map(:k => :v, :key => :val) # ruh-oh, the input hash loses order! m = Map.new(:k => :v, :key => :val) # ruh-oh, the input hash loses order! m = Map.new m[:a] = 0 m[:b] = 1 m[:c] = 2 p m.keys #=> ['a','b','c'] ### always ordered! p m.values #=> [0,1,2] ### always ordered! # maps don't care about symbol vs.string keys # p m[:a] #=> 0 p m["a"] #=> 0 # even via deep nesting # p m[:foo]['bar'][:baz] #=> 42 # many functions operate in a way one would expect from an ordered container # m.update(:k2 => :v2) m.update(:k2, :v2) key_val_pair = m.shift key_val_pair = m.pop # maps keep mapiness for even deep operations # m.update :nested => {:hashes => {:are => :converted}} # maps can give back clever little struct objects # m = Map(:foo => {:bar => 42}) s = m.struct p s.foo.bar #=> 42 # because option parsing is such a common use case for needing string/symbol # indifference map.rb comes out of the box loaded with option support # def foo(*args, &block) opts = Map.options(args) a = opts.getopt(:a) b = opts.getopt(:b, :default => false) end opts = Map.options(:a => 42, :b => nil, :c => false) opts.getopt(:a) #=> 42 opts.getopt(:b) #=> nil opts.getopt(:b, :default => 42) #=> 42 opts.getopt(:c) #=> false opts.getopt(:d, :default => false) #=> false # this avoids such bugs as # options = {:read_only => false} read_only = options[:read_only] || true # should be false but is true # with options this becomes # options = Map.options(:read_only => true) read_only = options.getopt(:read_only, :default => false) #=> true # maps support some really nice operators that hashes/orderedhashes do not # m = Map.new m.set(:h, :a, 0, 42) m.has?(:h, :a) #=> true p m #=> {'h' => {'a' => [42]}} m.set(:h, :a, 1, 42.0) p m #=> {'h' => {'a' => [42, 42.0]}} m.get(:h, :a, 1) #=> 42.0 m.get(:x, :y, :z) #=> nil m[:x][:y][:z] #=> raises exception! m = Map.new(:array => [0,1]) defaults = {:array => [nil, nil, 2]} m.apply(defaults) p m[:array] #=> [0,1,2] # they also support some different iteration styles # m = Map.new m.set( [:a, :b, :c, 0] => 0, [:a, :b, :c, 1] => 10, [:a, :b, :c, 2] => 20, [:a, :b, :c, 3] => 30 ) m.set(:x, :y, 42) m.set(:x, :z, 42.0) m.depth_first_each do |key, val| p key => val end #=> [:a, :b, :c, 0] => 0 #=> [:a, :b, :c, 1] => 10 #=> [:a, :b, :c, 2] => 20 #=> [:a, :b, :c, 3] => 30 #=> [:x, :y] => 42 #=> [:x, :z] => 42.0 USAGE see lib/map.rb and test/map_test.rb HISTORY 4.3.0: - support for dot keys. map.set('a.b.c' => 42) #=> {'a'=>{'b'=>{'c'=>42}}}
Project
map
the awesome ruby container you've always wanted: a string/symbol indifferent ordered hash that works in all rubies
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
Pull Requests
Development
Primary Language
Ruby
Licenses
same as ruby's
Dependencies
Project Readme