-
Notifications
You must be signed in to change notification settings - Fork 22
/
README
145 lines (113 loc) · 3.58 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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}}}