match_map 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +10 -0
- data/CHANGES +4 -0
- data/Gemfile +16 -3
- data/README.md +7 -4
- data/Rakefile +0 -3
- data/VERSION +1 -1
- data/lib/match_map/match_map_18.rb +15 -0
- data/lib/match_map/match_map_19.rb +12 -0
- data/lib/match_map.rb +34 -22
- data/test/helper.rb +8 -1
- data/test/test_match_map.rb +16 -13
- metadata +16 -32
data/.travis.yml
ADDED
data/CHANGES
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
2.0.0 !!!! THIS IS A BIG, BACKWARDS-INCOMPATIBLE CHANGE !!!!
|
2
|
+
MatchMap now always returns an array (possibly empty)
|
3
|
+
Changed to use 1.8/1.9 specific code to simplify things;
|
4
|
+
1.1.1 Fixed Proc; removed dependence on 1.9
|
1
5
|
1.1.0 Add a different optimize method and benchmarking code; now 1.9 only
|
2
6
|
1.0.0 Improve documentation and bump version to 1.0.0
|
3
7
|
0.5.0 Change underlying structures so return order is guaranteed; lost optimize in the process
|
data/Gemfile
CHANGED
@@ -6,11 +6,24 @@ source "http://rubygems.org"
|
|
6
6
|
# Add dependencies to develop your gem here.
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
|
9
|
+
if RUBY_VERSION =~ /^1.8/
|
10
|
+
gem 'hashery'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
group :documentation do
|
15
|
+
gem "yard", "~> 0.6.0"
|
16
|
+
end
|
9
17
|
|
10
18
|
group :development do
|
11
19
|
gem "minitest", ">= 0"
|
12
|
-
gem "
|
13
|
-
gem "bundler", "~> 1.0.0"
|
20
|
+
gem "bundler", "~> 1"
|
14
21
|
gem "jeweler", "~> 1.6.4"
|
15
|
-
gem 'turn', '>=0.9.3'
|
16
22
|
end
|
23
|
+
|
24
|
+
# Don't require 'turn' to format tests, but use it if you have it
|
25
|
+
# begin
|
26
|
+
# require 'turn'
|
27
|
+
# gem 'turn', '>=0.9.3'
|
28
|
+
# rescue LoadError
|
29
|
+
# end
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ mm['aa'] #=> ['apat']
|
|
16
16
|
mm['b'] #=> ['bpat1', 'bpat2']
|
17
17
|
mm['cob'] #=> ['bpat1', 'bpat2', 'bpat3'] # flattened one level!!!
|
18
18
|
mm['cab'] #=> ['apat', 'bpat1', 'bpat2', 'bpat3']
|
19
|
-
mm['c'] #=>
|
19
|
+
mm['c'] #=> [] # no match
|
20
20
|
|
21
21
|
|
22
22
|
# Change the default miss value to ease some processing forms
|
@@ -38,7 +38,7 @@ mm = MatchMap.new
|
|
38
38
|
mm[/ab/] = "AB"
|
39
39
|
|
40
40
|
# first, without echo
|
41
|
-
mm['miss'] =
|
41
|
+
mm['miss'] = []
|
42
42
|
mm['cab'] = ['AB']
|
43
43
|
|
44
44
|
#...then with echo = :always
|
@@ -60,6 +60,7 @@ end
|
|
60
60
|
|
61
61
|
A MatchMap is a hash-like with the following properties:
|
62
62
|
|
63
|
+
* The return value is always a (possibly empty) array
|
63
64
|
* keys can be anything that responds to '==' (e.g., strings) or regular expressions
|
64
65
|
* keys cannot be repeated (mirroring how a hash works, but see below about multiple values)
|
65
66
|
* arguments are compared to non-pattern keys based on ==
|
@@ -120,9 +121,11 @@ Here's a quick example to show how it works
|
|
120
121
|
|
121
122
|
You can also use a Proc object as a value. It must:
|
122
123
|
|
123
|
-
* take a single argument; the match variable
|
124
|
+
* take a single argument; the match variable (if your key was a Regexp) or the string matched
|
124
125
|
* return a (possibly empty) _array of values_
|
125
126
|
|
127
|
+
It doesn't make a lot of sense to use a Proc value if your key is just a scalar, but it's possible.
|
128
|
+
|
126
129
|
This can be abused, of course, but can be useful. Here's a simple example that reverses the order of a comma-delimited duple.
|
127
130
|
|
128
131
|
```ruby
|
@@ -175,7 +178,7 @@ Obviously, only call `#optimize!` when you're sure you won't be modifying the ma
|
|
175
178
|
## Gotchas
|
176
179
|
|
177
180
|
* Like a hash, repeated assignment to the same key results in a replacement. So `mm[/a/] = 'a'; mm[/a/] = 'A'` will give `mm['a'] #=> ['A']`
|
178
|
-
* Return values are flattened one level. So, a => 1 and b => [2,3], the something that matches both will return [1,2,3]. If you really want to return an array, you need to do something like `m['a'] = [[1,2]]`
|
181
|
+
* Return values are flattened one level. So, /a/ => 1 and b => [2,3], the something that matches both will return [1,2,3]. If you really want to return an array, you need to do something like `m['a'] = [[1,2]]`
|
179
182
|
|
180
183
|
|
181
184
|
## Contributing to MatchMap
|
data/Rakefile
CHANGED
@@ -14,7 +14,6 @@ require 'rake'
|
|
14
14
|
require 'jeweler'
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.required_ruby_version = '>= 1.9.0' # due to use of define_singleton_method in optimize
|
18
17
|
gem.name = "match_map"
|
19
18
|
gem.homepage = "http://github.com/billdueber/match_map"
|
20
19
|
gem.license = "MIT"
|
@@ -43,5 +42,3 @@ end
|
|
43
42
|
|
44
43
|
task :default => :test
|
45
44
|
|
46
|
-
require 'yard'
|
47
|
-
YARD::Rake::YardocTask.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# In ruby 1.8x, the Hashes are not ordered, so we fall back on
|
2
|
+
# the hashery ordered_hash
|
3
|
+
|
4
|
+
require 'hashery/ordered_hash'
|
5
|
+
|
6
|
+
module MatchMapIncludes
|
7
|
+
module OnePointEight
|
8
|
+
# 1.8 setup
|
9
|
+
def setup h
|
10
|
+
singleton_class = class << self; self; end
|
11
|
+
singleton_class.send(:define_method, :inner_get, method(:normal_inner_get))
|
12
|
+
@map = OrderedHash.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/match_map.rb
CHANGED
@@ -4,21 +4,45 @@
|
|
4
4
|
|
5
5
|
class MatchMap
|
6
6
|
|
7
|
-
#
|
8
7
|
attr_accessor :default
|
9
8
|
attr_reader :echo
|
10
9
|
|
10
|
+
if RUBY_VERSION =~ /^1\.9/
|
11
|
+
require 'match_map/match_map_19'
|
12
|
+
include MatchMapIncludes::OnePointNine
|
13
|
+
else
|
14
|
+
require 'match_map/match_map_18'
|
15
|
+
include MatchMapIncludes::OnePointEight
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize h = {}
|
19
|
+
@default = nil # default miss value is nil
|
20
|
+
@attrs = {}
|
21
|
+
# Set up the appripriate @map and define which inner_get to use
|
22
|
+
self.setup h
|
23
|
+
|
24
|
+
# Initialize with the given hash
|
25
|
+
h.each_pair do |k, v|
|
26
|
+
self[k] = v
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
11
30
|
|
12
|
-
def
|
13
|
-
|
14
|
-
@echo = arg
|
31
|
+
def delete key
|
32
|
+
@map.delete(key)
|
15
33
|
end
|
16
34
|
|
35
|
+
|
17
36
|
def []= key, val
|
18
37
|
@map[key] = val
|
19
|
-
@keys.push key unless @keys.include? key
|
20
38
|
set_attrs key, val
|
21
39
|
end
|
40
|
+
|
41
|
+
def echo= arg
|
42
|
+
raise RuntimeError.new, "echo value must be :onmiss or :always" unless [:onmiss, :always].include? arg
|
43
|
+
@echo = arg
|
44
|
+
end
|
45
|
+
|
22
46
|
|
23
47
|
def set_attrs key, val
|
24
48
|
@attrs[key] = {:regexkey => (key.is_a? Regexp), :procval => (val.is_a? Proc)}
|
@@ -39,7 +63,7 @@ class MatchMap
|
|
39
63
|
if @echo == :onmiss
|
40
64
|
return [*arg]
|
41
65
|
else
|
42
|
-
return @default
|
66
|
+
return [@default].compact
|
43
67
|
end
|
44
68
|
end
|
45
69
|
return rv
|
@@ -51,7 +75,7 @@ class MatchMap
|
|
51
75
|
|
52
76
|
def normal_inner_get arg
|
53
77
|
rv = []
|
54
|
-
@keys.each do |k|
|
78
|
+
@map.keys.each do |k|
|
55
79
|
if k.is_a? Regexp
|
56
80
|
m = k.match arg.to_s
|
57
81
|
else
|
@@ -74,29 +98,17 @@ class MatchMap
|
|
74
98
|
@map.has_key? key
|
75
99
|
end
|
76
100
|
|
77
|
-
def delete key
|
78
|
-
@map.delete(key)
|
79
|
-
@keys.delete(key)
|
80
|
-
end
|
81
101
|
|
82
|
-
def initialize hash = {}
|
83
|
-
@default = nil # default miss value is nil
|
84
|
-
@echo = echo
|
85
|
-
@keys = hash.keys
|
86
|
-
@map = hash
|
87
|
-
@attrs = {}
|
88
|
-
@map.each_pair {|k, v| set_attrs k, v}
|
89
|
-
define_singleton_method :inner_get, method(:normal_inner_get)
|
90
|
-
end
|
91
102
|
|
92
103
|
def optimize!
|
104
|
+
singleton_class = class << self; self; end
|
93
105
|
@map.each_pair do |k,v|
|
94
106
|
if k.is_a? Regexp or v.is_a? Proc
|
95
|
-
|
107
|
+
singleton_class.send(:define_method, :inner_get, method(:normal_inner_get))
|
96
108
|
return
|
97
109
|
end
|
98
110
|
end
|
99
|
-
|
111
|
+
singleton_class.send(:define_method, :inner_get, method(:optimized_inner_get))
|
100
112
|
end
|
101
113
|
|
102
114
|
end
|
data/test/helper.rb
CHANGED
@@ -9,7 +9,14 @@ rescue Bundler::BundlerError => e
|
|
9
9
|
end
|
10
10
|
require 'minitest/spec'
|
11
11
|
require 'minitest/benchmark'
|
12
|
-
|
12
|
+
# if RUBY_VERSION =~ /^1.9/
|
13
|
+
# begin
|
14
|
+
# require 'turn/autorun'
|
15
|
+
# # f = ENV['format'] || 'progress'
|
16
|
+
# # Turn.config.format = f.to_sym if f
|
17
|
+
# rescue LoadError
|
18
|
+
# end
|
19
|
+
# end
|
13
20
|
|
14
21
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
22
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
data/test/test_match_map.rb
CHANGED
@@ -8,13 +8,13 @@ describe MatchMap do
|
|
8
8
|
|
9
9
|
describe "when empty" do
|
10
10
|
|
11
|
-
it "should return
|
12
|
-
@h['a'].must_equal
|
11
|
+
it "should return empty array (default)" do
|
12
|
+
@h['a'].must_equal []
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should allow set of default' do
|
16
16
|
@h.default = 'def'
|
17
|
-
@h['a'].must_equal 'def'
|
17
|
+
@h['a'].must_equal ['def']
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
@@ -25,9 +25,9 @@ describe MatchMap do
|
|
25
25
|
@h['a'].must_equal [3]
|
26
26
|
end
|
27
27
|
|
28
|
-
it 'should still return default' do
|
28
|
+
it 'should still return default in an array ([] if default is nil)' do
|
29
29
|
@h['a'] = 3
|
30
|
-
@h['c'].must_equal
|
30
|
+
@h['c'].must_equal []
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should reset a value' do
|
@@ -52,7 +52,7 @@ describe MatchMap do
|
|
52
52
|
@h.has_key?('c').must_equal false
|
53
53
|
@h.delete('a')
|
54
54
|
@h.has_key?('a').must_equal false
|
55
|
-
@h['a'].must_equal
|
55
|
+
@h['a'].must_equal []
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -68,8 +68,8 @@ describe MatchMap do
|
|
68
68
|
|
69
69
|
it "uses a single pattern" do
|
70
70
|
@h[/.+a/] = 1
|
71
|
-
@h['b'].must_equal
|
72
|
-
@h['a'].must_equal
|
71
|
+
@h['b'].must_equal []
|
72
|
+
@h['a'].must_equal []
|
73
73
|
@h['aa'].must_equal [1]
|
74
74
|
@h['era'].must_equal [1]
|
75
75
|
end
|
@@ -119,10 +119,13 @@ describe MatchMap do
|
|
119
119
|
mm['Dueber, Bill'].must_equal ["Bill Dueber"]
|
120
120
|
end
|
121
121
|
|
122
|
-
it "calls the Proc for string argument, even though that kind of an abuse" do
|
122
|
+
it "calls the Proc for string argument, even though that is kind of an abuse" do
|
123
123
|
mm = MatchMap.new
|
124
|
-
mm['a'] = Proc.new {|m| [m
|
124
|
+
mm['a'] = Proc.new {|m| [(m + 'bbb')]}
|
125
125
|
mm['a'].must_equal ['abbb']
|
126
|
+
|
127
|
+
mm[/b(.*)/] = Proc.new {|m| [m[1]]}
|
128
|
+
mm['b123'].must_equal ['123']
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
@@ -132,7 +135,7 @@ describe MatchMap do
|
|
132
135
|
end
|
133
136
|
|
134
137
|
it "echos when empty" do
|
135
|
-
@j['miss'].must_equal
|
138
|
+
@j['miss'].must_equal [] # no echoing
|
136
139
|
|
137
140
|
@j.echo = :always
|
138
141
|
@j['miss'].must_equal ['miss']
|
@@ -144,7 +147,7 @@ describe MatchMap do
|
|
144
147
|
it "echos when not empty" do
|
145
148
|
@j[/a/] = 'hello'
|
146
149
|
|
147
|
-
@j['miss'].must_equal
|
150
|
+
@j['miss'].must_equal []
|
148
151
|
|
149
152
|
@j.echo = :always
|
150
153
|
@j['miss'].must_equal ['miss']
|
@@ -183,7 +186,7 @@ describe MatchMap do
|
|
183
186
|
end
|
184
187
|
|
185
188
|
it 'misses hard' do
|
186
|
-
@h[[1,2,3]].must_equal
|
189
|
+
@h[[1,2,3]].must_equal []
|
187
190
|
end
|
188
191
|
|
189
192
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: match_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
|
-
requirement: &
|
16
|
+
requirement: &2168628360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,32 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: yard
|
27
|
-
requirement: &70104080321880 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 0.6.0
|
33
|
-
type: :development
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70104080321880
|
24
|
+
version_requirements: *2168628360
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: bundler
|
38
|
-
requirement: &
|
27
|
+
requirement: &2168624380 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ~>
|
42
31
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1
|
32
|
+
version: '1'
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *2168624380
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: jeweler
|
49
|
-
requirement: &
|
38
|
+
requirement: &2168621520 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ~>
|
@@ -54,18 +43,7 @@ dependencies:
|
|
54
43
|
version: 1.6.4
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: turn
|
60
|
-
requirement: &70104080319220 !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ! '>='
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version: 0.9.3
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *70104080319220
|
46
|
+
version_requirements: *2168621520
|
69
47
|
description: ! "MatchMap is a map representing key=>value pairs but where \n (a)
|
70
48
|
a query argument can match more than one key, and (b) the argument is compraed to
|
71
49
|
the key\n such that you can use regex patterns as keys"
|
@@ -77,6 +55,7 @@ extra_rdoc_files:
|
|
77
55
|
- README.md
|
78
56
|
files:
|
79
57
|
- .document
|
58
|
+
- .travis.yml
|
80
59
|
- CHANGES
|
81
60
|
- Gemfile
|
82
61
|
- LICENSE.txt
|
@@ -85,6 +64,8 @@ files:
|
|
85
64
|
- VERSION
|
86
65
|
- bench/bench.rb
|
87
66
|
- lib/match_map.rb
|
67
|
+
- lib/match_map/match_map_18.rb
|
68
|
+
- lib/match_map/match_map_19.rb
|
88
69
|
- test/helper.rb
|
89
70
|
- test/test_match_map.rb
|
90
71
|
homepage: http://github.com/billdueber/match_map
|
@@ -99,7 +80,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
80
|
requirements:
|
100
81
|
- - ! '>='
|
101
82
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
83
|
+
version: '0'
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: 2828716471477841812
|
103
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
88
|
none: false
|
105
89
|
requirements:
|