pattern-match 0.0.1 → 0.0.2
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/README.rdoc +83 -1
- data/lib/pattern-match/version.rb +1 -1
- data/lib/pattern-match.rb +26 -2
- data/test/test_pattern-match.rb +42 -2
- metadata +6 -6
data/README.rdoc
CHANGED
@@ -15,7 +15,89 @@ or
|
|
15
15
|
$ bundle install --path vendor/bundle
|
16
16
|
|
17
17
|
== Example
|
18
|
-
|
18
|
+
require 'pattern-match'
|
19
|
+
|
20
|
+
## (A)
|
21
|
+
match([0, [1, 2, 3, 4]]) {
|
22
|
+
with(_[a, _[b, *c, d]]) { # Same as `Array.(a, Array.(b, *c, d))'
|
23
|
+
p [a, b, c, d] #=> [0, 1, [2, 3], 4]
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
## (B)
|
28
|
+
# From util.match in Gauche: http://practical-scheme.net/gauche/man/?l=en&p=util.match
|
29
|
+
match([[0, 1], [2, 3]]) {
|
30
|
+
with(_[_[a, b], ___]) {
|
31
|
+
p [a, b] #=> [[0, 2], [1, 3]]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
## (C)
|
36
|
+
# balance in a red-black tree
|
37
|
+
Node = Struct.new(:left, :key, :right)
|
38
|
+
class R < Node; end
|
39
|
+
class B < Node; end
|
40
|
+
|
41
|
+
def balance(left, key, right)
|
42
|
+
match([left, key, right]) {
|
43
|
+
with(_[R.(a, x, b), y, R.(c, z, d)]) { R[B[a, x, b], y, B[c, z, d]] }
|
44
|
+
with(_[R.(R.(a, x, b), y, c), z, d]) { R[B[a, x, b], y, B[c, z, d]] }
|
45
|
+
with(_[R.(a, x, R.(b, y, c)), z, d]) { R[B[a, x, b], y, B[c, z, d]] }
|
46
|
+
with(_[a, x, R.(b, y, R.(c, z, d))]) { R[B[a, x, b], y, B[c, z, d]] }
|
47
|
+
with(_[a, x, R.(R.(b, y, c), z, d)]) { R[B[a, x, b], y, B[c, z, d]] }
|
48
|
+
with(_) { B[left, key, right] }
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# With Refinements
|
53
|
+
def balance(left, key, right)
|
54
|
+
match([left, key, right]) {
|
55
|
+
with(_[R[a, x, b], y, R[c, z, d]]) { R[B[a, x, b], y, B[c, z, d]] }
|
56
|
+
with(_[R[R[a, x, b], y, c], z, d]) { R[B[a, x, b], y, B[c, z, d]] }
|
57
|
+
with(_[R[a, x, R[b, y, c]], z, d]) { R[B[a, x, b], y, B[c, z, d]] }
|
58
|
+
with(_[a, x, R[b, y, R[c, z, d]]]) { R[B[a, x, b], y, B[c, z, d]] }
|
59
|
+
with(_[a, x, R[R[b, y, c], z, d]]) { R[B[a, x, b], y, B[c, z, d]] }
|
60
|
+
with(_) { B[left, key, right] }
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
## (D)
|
65
|
+
class EMail
|
66
|
+
def self.extract(value)
|
67
|
+
value.to_s.split(/@/).tap {|parts| raise PatternNotMatch unless parts.length == 2 }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
match(['foo-bar@example.com', 'baz-bar@example.com']) {
|
72
|
+
with(_[mail & EMail.(name & /(\w+)-(\w+)/.(firstname, 'bar'), domain), ___]) {
|
73
|
+
p [firstname, name, domain, mail] # => [["foo", "baz"], ["foo-bar", "baz-bar"], ["example.com", "example.com"], ["foo-bar@example.com", "baz-bar@example.com"]]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
# With Refinements
|
78
|
+
match(['foo-bar@example.com', 'baz-bar@example.com']) {
|
79
|
+
with(_[mail & EMail[name & /(\w+)-(\w+)/[firstname, 'bar'], domain], ___]) {
|
80
|
+
p [firstname, name, domain, mail] # => [["foo", "baz"], ["foo-bar", "baz-bar"], ["example.com", "example.com"], ["foo-bar@example.com", "baz-bar@example.com"]]
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
## (E)
|
85
|
+
match(10) {
|
86
|
+
with(Object.(:to_i => a, :foobar => b)) { :not_match }
|
87
|
+
with(Object.(:to_i => a, :to_s.(16) => b)) {
|
88
|
+
p [a, b] #=> [10, "a"]
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
# With Refinements
|
93
|
+
match(10) {
|
94
|
+
with(:to_i[a] & :foobar[b]) { :not_match }
|
95
|
+
with(:to_i[a] & :to_s.(16)[b])) {
|
96
|
+
p [a, b] #=> [10, "a"]
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
You can see another example in test/test_pattern-match.rb.
|
19
101
|
|
20
102
|
== Development
|
21
103
|
$ git clone git://github.com/k-tsj/pattern-match.git
|
data/lib/pattern-match.rb
CHANGED
@@ -61,6 +61,27 @@ module PatternMatch
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
refine Complex.singleton_class do
|
65
|
+
def extract(val)
|
66
|
+
accept_self_instance_only(val)
|
67
|
+
val.rect
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
refine Rational.singleton_class do
|
72
|
+
def extract(val)
|
73
|
+
accept_self_instance_only(val)
|
74
|
+
[val.numerator, val.denominator]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
refine MatchData.singleton_class do
|
79
|
+
def extract(val)
|
80
|
+
accept_self_instance_only(val)
|
81
|
+
val.captures.empty? ? [val[0]] : val.captures
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
64
85
|
if SUPPORT_REFINEMENTS
|
65
86
|
def Struct.method_added(name)
|
66
87
|
if name == members[0]
|
@@ -301,13 +322,14 @@ module PatternMatch
|
|
301
322
|
end
|
302
323
|
|
303
324
|
class PatternValue < Pattern
|
304
|
-
def initialize(val)
|
325
|
+
def initialize(val, compare_by = :===)
|
305
326
|
super()
|
306
327
|
@val = val
|
328
|
+
@compare_by = compare_by
|
307
329
|
end
|
308
330
|
|
309
331
|
def match(val)
|
310
|
-
@val
|
332
|
+
@val.send(@compare_by, val)
|
311
333
|
end
|
312
334
|
end
|
313
335
|
|
@@ -410,6 +432,8 @@ module PatternMatch
|
|
410
432
|
uscore
|
411
433
|
when 1
|
412
434
|
PatternValue.new(vals[0])
|
435
|
+
when 2
|
436
|
+
PatternValue.new(vals[0], vals[1])
|
413
437
|
else
|
414
438
|
raise MalformedPatternError
|
415
439
|
end
|
data/test/test_pattern-match.rb
CHANGED
@@ -52,8 +52,8 @@ class TestPatternMatch < Test::Unit::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_uscore
|
55
|
-
match([0, 1]) {
|
56
|
-
with(_[_, ! _(Float)]) {
|
55
|
+
match([0, 1, Fixnum]) {
|
56
|
+
with(_[_, ! _(Float), _(Fixnum, :==)]) {
|
57
57
|
assert_raise(NameError) { _ }
|
58
58
|
}
|
59
59
|
with(_) { flunk }
|
@@ -279,6 +279,46 @@ class TestPatternMatch < Test::Unit::TestCase
|
|
279
279
|
}
|
280
280
|
end
|
281
281
|
|
282
|
+
def test_extractor_class_complex
|
283
|
+
match(Complex(0, 1)) {
|
284
|
+
with(Complex.(a, b)) {
|
285
|
+
assert_equal(0, a)
|
286
|
+
assert_equal(1, b)
|
287
|
+
}
|
288
|
+
with(_) { flunk }
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_extractor_class_rational
|
293
|
+
match(Rational(0, 1)) {
|
294
|
+
with(Rational.(a, b)) {
|
295
|
+
assert_equal(0, a)
|
296
|
+
assert_equal(1, b)
|
297
|
+
}
|
298
|
+
with(_) { flunk }
|
299
|
+
}
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_extractor_class_matchdata
|
303
|
+
m = /.../.match('abc')
|
304
|
+
match(m) {
|
305
|
+
with(MatchData.(a)) {
|
306
|
+
assert_equal('abc', a)
|
307
|
+
}
|
308
|
+
with(_) { flunk }
|
309
|
+
}
|
310
|
+
|
311
|
+
m = /(.)(.)(.)/.match('abc')
|
312
|
+
match(m) {
|
313
|
+
with(MatchData.(a, b, c)) {
|
314
|
+
assert_equal('a', a)
|
315
|
+
assert_equal('b', b)
|
316
|
+
assert_equal('c', c)
|
317
|
+
}
|
318
|
+
with(_) { flunk }
|
319
|
+
}
|
320
|
+
end
|
321
|
+
|
282
322
|
def test_extractor_obj_regexp
|
283
323
|
match('abc') {
|
284
324
|
with(/./.(a)) { flunk }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pattern-match
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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-03-
|
12
|
+
date: 2012-03-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &6408560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *6408560
|
25
25
|
description: A pattern matching library.
|
26
26
|
email:
|
27
27
|
- kazuki@callcc.net
|
@@ -57,7 +57,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
57
|
version: '0'
|
58
58
|
segments:
|
59
59
|
- 0
|
60
|
-
hash:
|
60
|
+
hash: 2122497246809249036
|
61
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
66
|
version: '0'
|
67
67
|
segments:
|
68
68
|
- 0
|
69
|
-
hash:
|
69
|
+
hash: 2122497246809249036
|
70
70
|
requirements: []
|
71
71
|
rubyforge_project:
|
72
72
|
rubygems_version: 1.8.11
|