pattern-match 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|