mug 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mug.rb +14 -13
- data/lib/mug/and-or.rb +48 -48
- data/lib/mug/apply.rb +58 -58
- data/lib/mug/array.rb +1 -0
- data/lib/mug/array/extend.rb +69 -0
- data/lib/mug/bool.rb +128 -128
- data/lib/mug/fragile-method-chain.rb +70 -70
- data/lib/mug/hash.rb +2 -0
- data/lib/mug/hash/map.rb +100 -0
- data/lib/mug/hash/operations.rb +54 -0
- data/lib/mug/hashmap.rb +2 -100
- data/lib/mug/hashop.rb +2 -54
- data/lib/mug/iterator.rb +2 -2
- data/lib/mug/iterator/for.rb +29 -29
- data/lib/mug/iterator/method.rb +29 -29
- data/lib/mug/iterator_c.rb +44 -44
- data/lib/mug/maybe.rb +59 -59
- data/lib/mug/self.rb +33 -33
- data/lib/mug/tau.rb +44 -44
- data/lib/mug/to_h.rb +48 -44
- data/test/test-and-or.rb +41 -41
- data/test/test-array-extend.rb +67 -0
- data/test/test-bool.rb +70 -70
- data/test/test-fragile-method-chain.rb +65 -65
- data/test/test-hashmap.rb +24 -24
- data/test/test-hashop.rb +62 -62
- data/test/test-iterator-for.rb +18 -18
- data/test/test-iterator-method.rb +18 -18
- data/test/test-maybe.rb +90 -90
- data/test/test-self.rb +13 -13
- data/test/test-tau.rb +22 -22
- data/test/test-to_h.rb +16 -16
- data/test/test_apply.rb +56 -56
- metadata +50 -36
- checksums.yaml +0 -7
@@ -1,70 +1,70 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Invokes a method chain until one method returns a falsy value.
|
4
|
-
#
|
5
|
-
# For example:
|
6
|
-
#
|
7
|
-
# a._?.b.c.d._!
|
8
|
-
# nested_hash._?[:a][:b][:c]._!
|
9
|
-
#
|
10
|
-
class FragileMethodChain
|
11
|
-
#
|
12
|
-
# Creates a FragileMethodChain which will send its first method to +o+
|
13
|
-
#
|
14
|
-
def initialize o
|
15
|
-
@o = o
|
16
|
-
@chain = []
|
17
|
-
end
|
18
|
-
|
19
|
-
#
|
20
|
-
# Finalises the FragileMethodChain.
|
21
|
-
#
|
22
|
-
# The final result will be the first +nil+ or +false+ value
|
23
|
-
# returned in the chain, or its end result.
|
24
|
-
#
|
25
|
-
def _!
|
26
|
-
@chain.inject(@o) do |o,x|
|
27
|
-
a,b = x
|
28
|
-
break o unless o
|
29
|
-
o.__send__(*a, &b)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Record the method args/block
|
34
|
-
def method_missing *a, &b #:nodoc:
|
35
|
-
@chain << [a,b]
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
# Explicitly record :_? as a method in the chain.
|
40
|
-
def _? #:nodoc:
|
41
|
-
@chain << [[ :_? ],nil]
|
42
|
-
self
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class Object
|
47
|
-
#
|
48
|
-
# Begins a FragileMethodChain.
|
49
|
-
#
|
50
|
-
def _?
|
51
|
-
FragileMethodChain.new(self)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
=begin
|
56
|
-
Copyright (c) 2013, Matthew Kerwin <matthew@kerwin.net.au>
|
57
|
-
|
58
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
59
|
-
purpose with or without fee is hereby granted, provided that the above
|
60
|
-
copyright notice and this permission notice appear in all copies.
|
61
|
-
|
62
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
63
|
-
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
64
|
-
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
65
|
-
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
66
|
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
67
|
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
68
|
-
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
69
|
-
=end
|
70
|
-
|
1
|
+
|
2
|
+
#
|
3
|
+
# Invokes a method chain until one method returns a falsy value.
|
4
|
+
#
|
5
|
+
# For example:
|
6
|
+
#
|
7
|
+
# a._?.b.c.d._!
|
8
|
+
# nested_hash._?[:a][:b][:c]._!
|
9
|
+
#
|
10
|
+
class FragileMethodChain
|
11
|
+
#
|
12
|
+
# Creates a FragileMethodChain which will send its first method to +o+
|
13
|
+
#
|
14
|
+
def initialize o
|
15
|
+
@o = o
|
16
|
+
@chain = []
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Finalises the FragileMethodChain.
|
21
|
+
#
|
22
|
+
# The final result will be the first +nil+ or +false+ value
|
23
|
+
# returned in the chain, or its end result.
|
24
|
+
#
|
25
|
+
def _!
|
26
|
+
@chain.inject(@o) do |o,x|
|
27
|
+
a,b = x
|
28
|
+
break o unless o
|
29
|
+
o.__send__(*a, &b)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Record the method args/block
|
34
|
+
def method_missing *a, &b #:nodoc:
|
35
|
+
@chain << [a,b]
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Explicitly record :_? as a method in the chain.
|
40
|
+
def _? #:nodoc:
|
41
|
+
@chain << [[ :_? ],nil]
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Object
|
47
|
+
#
|
48
|
+
# Begins a FragileMethodChain.
|
49
|
+
#
|
50
|
+
def _?
|
51
|
+
FragileMethodChain.new(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
=begin
|
56
|
+
Copyright (c) 2013, Matthew Kerwin <matthew@kerwin.net.au>
|
57
|
+
|
58
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
59
|
+
purpose with or without fee is hereby granted, provided that the above
|
60
|
+
copyright notice and this permission notice appear in all copies.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
63
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
64
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
65
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
66
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
67
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
68
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
69
|
+
=end
|
70
|
+
|
data/lib/mug/hash.rb
ADDED
data/lib/mug/hash/map.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
|
2
|
+
class Hash
|
3
|
+
#
|
4
|
+
# Returns a new hash which is a copy of the current hash but each
|
5
|
+
# value is replaced by the result of running it through +block+.
|
6
|
+
#
|
7
|
+
# {'a'=>1, 'b'=>2}.map_values { |v| v*2 } #=> {'a'=>2, 'b'=>4}
|
8
|
+
# {'a'=>1, 'b'=>2}.map_values { "cat" } #=> {'a'=>"cat", 'b'=>"cat"}
|
9
|
+
#
|
10
|
+
def map_values &block # :yields: value
|
11
|
+
hsh = {}
|
12
|
+
each do |k, v|
|
13
|
+
hsh[k] = yield v
|
14
|
+
end
|
15
|
+
hsh
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Replaces the values in +hsh+ by running them each through +block+.
|
20
|
+
#
|
21
|
+
# See: #map_values
|
22
|
+
#
|
23
|
+
def map_values! &block # :yields: value
|
24
|
+
replace map_values(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Returns a new hash which is a copy of the current hash but each
|
29
|
+
# key is replaced by the result of running it through +block+.
|
30
|
+
#
|
31
|
+
# If +block+ returns duplicate keys, they will be overwritten in
|
32
|
+
# the resulting hash.
|
33
|
+
#
|
34
|
+
# {'a'=>1, 'b'=>2}.map_keys { |k| k*2 } #=> {'aa'=>1, 'bb'=>2}
|
35
|
+
# {'a'=>1, 'b'=>2}.map_keys { "cat" } #=> {'cat'=>2}
|
36
|
+
#
|
37
|
+
def map_keys &block # :yields: key
|
38
|
+
hsh = {}
|
39
|
+
each do |k, v|
|
40
|
+
hsh[ yield k ] = v
|
41
|
+
end
|
42
|
+
hsh
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Replaces the keys in +hsh+ by running them each through +block+.
|
47
|
+
#
|
48
|
+
# If +block+ returns duplicate keys, they will be overwritten in turn.
|
49
|
+
#
|
50
|
+
# See: #map_keys
|
51
|
+
#
|
52
|
+
def map_keys! &block # :yields: key
|
53
|
+
replace map_keys(&block)
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Returns a new hash which is a copy of the current hash but each
|
58
|
+
# key-value pair is replaced by the result of running it through +block+.
|
59
|
+
#
|
60
|
+
# If +block+ returns duplicate keys, they will be overwritten in
|
61
|
+
# the resulting hash.
|
62
|
+
#
|
63
|
+
# {'a'=>1, 'b'=>2}.map_pairs { |k,v| [k*2, v+1] } #=> {'aa'=>2, 'bb'=>3}
|
64
|
+
# {'a'=>1, 'b'=>2}.map_pairs { ["cat","dog"] } #=> {'cat'=>'dog'}
|
65
|
+
#
|
66
|
+
def map_pairs &block # :yields: key, value
|
67
|
+
hsh = {}
|
68
|
+
each do |k, v|
|
69
|
+
a, b = yield k, v
|
70
|
+
hsh[a] = b
|
71
|
+
end
|
72
|
+
hsh
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Replaces the values in +hsh+ by running them each through +block+.
|
77
|
+
#
|
78
|
+
# See: #map_values
|
79
|
+
#
|
80
|
+
def map_pairs! &block # :yields: key, value
|
81
|
+
replace map_pairs(&block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
=begin
|
86
|
+
Copyright (c) 2013, Matthew Kerwin <matthew@kerwin.net.au>
|
87
|
+
|
88
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
89
|
+
purpose with or without fee is hereby granted, provided that the above
|
90
|
+
copyright notice and this permission notice appear in all copies.
|
91
|
+
|
92
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
93
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
94
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
95
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
96
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
97
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
98
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
99
|
+
=end
|
100
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
class Hash
|
3
|
+
|
4
|
+
#
|
5
|
+
# Returns a new Hash, whose value is the same as this
|
6
|
+
# one, with any extras in +other_hash+ added in.
|
7
|
+
#
|
8
|
+
# Useful for default options.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# opts = {:a => 1, :b => 2 }
|
12
|
+
# dflt = {:a => 0, :x => 9 }
|
13
|
+
# opts |= dflt # => opts = {:a=>1, :b=>2, :x=>9}
|
14
|
+
#
|
15
|
+
def | other_hash
|
16
|
+
other_hash.merge self
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Adds the contents of +other_hash+ to +hsh+.
|
21
|
+
# Entries with duplicate keys are overwritten with the
|
22
|
+
# values from +other_hash+
|
23
|
+
#
|
24
|
+
def + other_hash
|
25
|
+
merge other_hash
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Appends stuff to the hash.
|
30
|
+
#
|
31
|
+
# If +o+ is a Hash, this is identical to calling #merge!
|
32
|
+
# If +o+ is an Array with two elements, it is interpreted as [key,value]
|
33
|
+
# If +o+ can be converted to a hash with #to_h, this is identical to calling #merge!
|
34
|
+
# Otherwise an ArgumentError is raised.
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
# h = {}
|
38
|
+
# h << {:a=>0} # h = {:a=>0}
|
39
|
+
# h << {:b=>2,:c=>3} # h = {:a=>0,:b=>2,:c=>3}
|
40
|
+
# h << [:a,1] # h = {:a=>1,:b=>2,:c=>3}
|
41
|
+
#
|
42
|
+
def << o
|
43
|
+
if o.respond_to? :to_hash
|
44
|
+
merge! o.to_hash
|
45
|
+
elsif o.respond_to?(:to_a) && (a = o.to_a) && a.length == 2
|
46
|
+
tap { store a[0], a[1] }
|
47
|
+
elsif o.respond_to? :to_h
|
48
|
+
merge! o.to_h
|
49
|
+
else
|
50
|
+
raise ArgumentError, "#{o.class.name} is not a Hash"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
data/lib/mug/hashmap.rb
CHANGED
@@ -1,100 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#
|
4
|
-
# Returns a new hash which is a copy of the current hash but each
|
5
|
-
# value is replaced by the result of running it through +block+.
|
6
|
-
#
|
7
|
-
# {'a'=>1, 'b'=>2}.map_values { |v| v*2 } #=> {'a'=>2, 'b'=>4}
|
8
|
-
# {'a'=>1, 'b'=>2}.map_values { "cat" } #=> {'a'=>"cat", 'b'=>"cat"}
|
9
|
-
#
|
10
|
-
def map_values &block # :yields: value
|
11
|
-
hsh = {}
|
12
|
-
each do |k, v|
|
13
|
-
hsh[k] = yield v
|
14
|
-
end
|
15
|
-
hsh
|
16
|
-
end
|
17
|
-
|
18
|
-
#
|
19
|
-
# Replaces the values in +hsh+ by running them each through +block+.
|
20
|
-
#
|
21
|
-
# See: #map_values
|
22
|
-
#
|
23
|
-
def map_values! &block # :yields: value
|
24
|
-
replace map_values(&block)
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Returns a new hash which is a copy of the current hash but each
|
29
|
-
# key is replaced by the result of running it through +block+.
|
30
|
-
#
|
31
|
-
# If +block+ returns duplicate keys, they will be overwritten in
|
32
|
-
# the resulting hash.
|
33
|
-
#
|
34
|
-
# {'a'=>1, 'b'=>2}.map_keys { |k| k*2 } #=> {'aa'=>1, 'bb'=>2}
|
35
|
-
# {'a'=>1, 'b'=>2}.map_keys { "cat" } #=> {'cat'=>2}
|
36
|
-
#
|
37
|
-
def map_keys &block # :yields: key
|
38
|
-
hsh = {}
|
39
|
-
each do |k, v|
|
40
|
-
hsh[ yield k ] = v
|
41
|
-
end
|
42
|
-
hsh
|
43
|
-
end
|
44
|
-
|
45
|
-
#
|
46
|
-
# Replaces the keys in +hsh+ by running them each through +block+.
|
47
|
-
#
|
48
|
-
# If +block+ returns duplicate keys, they will be overwritten in turn.
|
49
|
-
#
|
50
|
-
# See: #map_keys
|
51
|
-
#
|
52
|
-
def map_keys! &block # :yields: key
|
53
|
-
replace map_keys(&block)
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# Returns a new hash which is a copy of the current hash but each
|
58
|
-
# key-value pair is replaced by the result of running it through +block+.
|
59
|
-
#
|
60
|
-
# If +block+ returns duplicate keys, they will be overwritten in
|
61
|
-
# the resulting hash.
|
62
|
-
#
|
63
|
-
# {'a'=>1, 'b'=>2}.map_pairs { |k,v| [k*2, v+1] } #=> {'aa'=>2, 'bb'=>3}
|
64
|
-
# {'a'=>1, 'b'=>2}.map_pairs { ["cat","dog"] } #=> {'cat'=>'dog'}
|
65
|
-
#
|
66
|
-
def map_pairs &block # :yields: key, value
|
67
|
-
hsh = {}
|
68
|
-
each do |k, v|
|
69
|
-
a, b = yield k, v
|
70
|
-
hsh[a] = b
|
71
|
-
end
|
72
|
-
hsh
|
73
|
-
end
|
74
|
-
|
75
|
-
#
|
76
|
-
# Replaces the values in +hsh+ by running them each through +block+.
|
77
|
-
#
|
78
|
-
# See: #map_values
|
79
|
-
#
|
80
|
-
def map_pairs! &block # :yields: key, value
|
81
|
-
replace map_pairs(&block)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
=begin
|
86
|
-
Copyright (c) 2013, Matthew Kerwin <matthew@kerwin.net.au>
|
87
|
-
|
88
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
89
|
-
purpose with or without fee is hereby granted, provided that the above
|
90
|
-
copyright notice and this permission notice appear in all copies.
|
91
|
-
|
92
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
93
|
-
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
94
|
-
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
95
|
-
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
96
|
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
97
|
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
98
|
-
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
99
|
-
=end
|
100
|
-
|
1
|
+
warn 'mug/hashmap is deprecated, use /mug/hash/map'
|
2
|
+
require_relative 'hash/map'
|
data/lib/mug/hashop.rb
CHANGED
@@ -1,54 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
# Returns a new Hash, whose value is the same as this
|
6
|
-
# one, with any extras in +other_hash+ added in.
|
7
|
-
#
|
8
|
-
# Useful for default options.
|
9
|
-
#
|
10
|
-
# Example:
|
11
|
-
# opts = {:a => 1, :b => 2 }
|
12
|
-
# dflt = {:a => 0, :x => 9 }
|
13
|
-
# opts |= dflt # => opts = {:a=>1, :b=>2, :x=>9}
|
14
|
-
#
|
15
|
-
def | other_hash
|
16
|
-
other_hash.merge self
|
17
|
-
end
|
18
|
-
|
19
|
-
#
|
20
|
-
# Adds the contents of +other_hash+ to +hsh+.
|
21
|
-
# Entries with duplicate keys are overwritten with the
|
22
|
-
# values from +other_hash+
|
23
|
-
#
|
24
|
-
def + other_hash
|
25
|
-
merge other_hash
|
26
|
-
end
|
27
|
-
|
28
|
-
#
|
29
|
-
# Appends stuff to the hash.
|
30
|
-
#
|
31
|
-
# If +o+ is a Hash, this is identical to calling #merge!
|
32
|
-
# If +o+ is an Array with two elements, it is interpreted as [key,value]
|
33
|
-
# If +o+ can be converted to a hash with #to_h, this is identical to calling #merge!
|
34
|
-
# Otherwise an ArgumentError is raised.
|
35
|
-
#
|
36
|
-
# Example:
|
37
|
-
# h = {}
|
38
|
-
# h << {:a=>0} # h = {:a=>0}
|
39
|
-
# h << {:b=>2,:c=>3} # h = {:a=>0,:b=>2,:c=>3}
|
40
|
-
# h << [:a,1] # h = {:a=>1,:b=>2,:c=>3}
|
41
|
-
#
|
42
|
-
def << o
|
43
|
-
if o.respond_to? :to_hash
|
44
|
-
merge! o.to_hash
|
45
|
-
elsif o.respond_to?(:to_a) && (a = o.to_a) && a.length == 2
|
46
|
-
tap { store a[0], a[1] }
|
47
|
-
elsif o.respond_to? :to_h
|
48
|
-
merge! o.to_h
|
49
|
-
else
|
50
|
-
raise ArgumentError, "#{o.class.name} is not a Hash"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
1
|
+
warn 'mug/hashop is deprecated, use /mug/hash/operations'
|
2
|
+
require_relative 'hash/operations'
|