pattern-match 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/lib/pattern-match/version.rb +1 -1
- data/lib/pattern-match.rb +39 -30
- data/test/test_pattern-match.rb +58 -4
- metadata +6 -6
data/README.rdoc
CHANGED
data/lib/pattern-match.rb
CHANGED
@@ -9,7 +9,7 @@ module PatternMatch
|
|
9
9
|
SUPPORT_REFINEMENTS = true
|
10
10
|
else
|
11
11
|
SUPPORT_REFINEMENTS = false
|
12
|
-
Module.module_eval
|
12
|
+
Module.module_eval do
|
13
13
|
private
|
14
14
|
|
15
15
|
def refine(klass, &block)
|
@@ -18,10 +18,10 @@ module PatternMatch
|
|
18
18
|
|
19
19
|
def using(klass)
|
20
20
|
end
|
21
|
-
|
21
|
+
end
|
22
22
|
end
|
23
23
|
|
24
|
-
module
|
24
|
+
module Deconstructable
|
25
25
|
def call(*subpatterns)
|
26
26
|
if Object == self
|
27
27
|
raise MalformedPatternError unless subpatterns.length == 1
|
@@ -38,7 +38,11 @@ module PatternMatch
|
|
38
38
|
|
39
39
|
module NameSpace
|
40
40
|
refine Class do
|
41
|
-
include
|
41
|
+
include Deconstructable
|
42
|
+
|
43
|
+
def deconstruct(val)
|
44
|
+
raise NotImplementedError, "need to define `#{__method__}'"
|
45
|
+
end
|
42
46
|
|
43
47
|
private
|
44
48
|
|
@@ -48,35 +52,35 @@ module PatternMatch
|
|
48
52
|
end
|
49
53
|
|
50
54
|
refine Array.singleton_class do
|
51
|
-
def
|
55
|
+
def deconstruct(val)
|
52
56
|
accept_self_instance_only(val)
|
53
57
|
val
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
61
|
refine Struct.singleton_class do
|
58
|
-
def
|
62
|
+
def deconstruct(val)
|
59
63
|
accept_self_instance_only(val)
|
60
64
|
val.values
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
68
|
refine Complex.singleton_class do
|
65
|
-
def
|
69
|
+
def deconstruct(val)
|
66
70
|
accept_self_instance_only(val)
|
67
71
|
val.rect
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
71
75
|
refine Rational.singleton_class do
|
72
|
-
def
|
76
|
+
def deconstruct(val)
|
73
77
|
accept_self_instance_only(val)
|
74
78
|
[val.numerator, val.denominator]
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
78
82
|
refine MatchData.singleton_class do
|
79
|
-
def
|
83
|
+
def deconstruct(val)
|
80
84
|
accept_self_instance_only(val)
|
81
85
|
val.captures.empty? ? [val[0]] : val.captures
|
82
86
|
end
|
@@ -86,26 +90,26 @@ module PatternMatch
|
|
86
90
|
def Struct.method_added(name)
|
87
91
|
if name == members[0]
|
88
92
|
this = self
|
89
|
-
PatternMatch::NameSpace.module_eval
|
93
|
+
PatternMatch::NameSpace.module_eval do
|
90
94
|
refine this.singleton_class do
|
91
|
-
include
|
95
|
+
include Deconstructable
|
92
96
|
end
|
93
|
-
|
97
|
+
end
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
97
101
|
refine Proc do
|
98
|
-
include
|
102
|
+
include Deconstructable
|
99
103
|
|
100
|
-
def
|
104
|
+
def deconstruct(val)
|
101
105
|
[self === val]
|
102
106
|
end
|
103
107
|
end
|
104
108
|
|
105
109
|
refine Symbol do
|
106
|
-
include
|
110
|
+
include Deconstructable
|
107
111
|
|
108
|
-
def
|
112
|
+
def deconstruct(val)
|
109
113
|
[self.to_proc === val]
|
110
114
|
end
|
111
115
|
end
|
@@ -113,14 +117,14 @@ module PatternMatch
|
|
113
117
|
|
114
118
|
refine Symbol do
|
115
119
|
def call(*args)
|
116
|
-
Proc.new {|obj| obj.
|
120
|
+
Proc.new {|obj| obj.__send__(self, *args) }
|
117
121
|
end
|
118
122
|
end
|
119
123
|
|
120
124
|
refine Regexp do
|
121
|
-
include
|
125
|
+
include Deconstructable
|
122
126
|
|
123
|
-
def
|
127
|
+
def deconstruct(val)
|
124
128
|
m = Regexp.new("\\A#{source}\\z", options).match(val.to_s)
|
125
129
|
raise PatternNotMatch unless m
|
126
130
|
m.captures.empty? ? [m[0]] : m.captures
|
@@ -142,7 +146,7 @@ module PatternMatch
|
|
142
146
|
end
|
143
147
|
|
144
148
|
def vars
|
145
|
-
@subpatterns.map(&:vars).
|
149
|
+
@subpatterns.map(&:vars).flatten
|
146
150
|
end
|
147
151
|
|
148
152
|
def binding
|
@@ -230,7 +234,7 @@ module PatternMatch
|
|
230
234
|
end
|
231
235
|
|
232
236
|
def match(val)
|
233
|
-
extracted_vals = pattern_match_env.call_refined_method(@extractor, :
|
237
|
+
extracted_vals = pattern_match_env.call_refined_method(@extractor, :deconstruct, val)
|
234
238
|
k = extracted_vals.length - (@subpatterns.length - 2)
|
235
239
|
quantifier = @subpatterns.find {|i| i.is_a?(PatternQuantifier) }
|
236
240
|
if quantifier
|
@@ -329,7 +333,7 @@ module PatternMatch
|
|
329
333
|
end
|
330
334
|
|
331
335
|
def match(val)
|
332
|
-
@val.
|
336
|
+
@val.__send__(@compare_by, val)
|
333
337
|
end
|
334
338
|
end
|
335
339
|
|
@@ -357,10 +361,6 @@ module PatternMatch
|
|
357
361
|
end
|
358
362
|
|
359
363
|
class PatternNot < Pattern
|
360
|
-
def initialize(subpattern)
|
361
|
-
super
|
362
|
-
end
|
363
|
-
|
364
364
|
def match(val)
|
365
365
|
! @subpatterns[0].match(val)
|
366
366
|
rescue PatternNotMatch
|
@@ -446,13 +446,19 @@ module PatternMatch
|
|
446
446
|
tmpbinding_module(obj).instance_eval do
|
447
447
|
begin
|
448
448
|
binding.each do |name, val|
|
449
|
-
|
450
|
-
|
449
|
+
stack = @stacks[name]
|
450
|
+
if stack.empty?
|
451
|
+
define_method(name) { stack[-1] }
|
452
|
+
private name
|
453
|
+
end
|
454
|
+
stack.push(val)
|
451
455
|
end
|
452
456
|
obj.instance_eval(&block)
|
453
457
|
ensure
|
454
458
|
binding.each do |name, _|
|
455
|
-
|
459
|
+
if @stacks[name].tap(&:pop).empty?
|
460
|
+
remove_method(name)
|
461
|
+
end
|
456
462
|
end
|
457
463
|
end
|
458
464
|
end
|
@@ -465,6 +471,9 @@ module PatternMatch
|
|
465
471
|
m = obj.singleton_class.ancestors.find {|i| i.is_a? TmpBindingModule }
|
466
472
|
unless m
|
467
473
|
m = TmpBindingModule.new
|
474
|
+
m.instance_eval do
|
475
|
+
@stacks = ::Hash.new {|h, k| h[k] = [] }
|
476
|
+
end
|
468
477
|
obj.extend(m)
|
469
478
|
end
|
470
479
|
m
|
@@ -486,7 +495,7 @@ module Kernel
|
|
486
495
|
using ::PatternMatch::NameSpace
|
487
496
|
|
488
497
|
def call_refined_method(obj, name, *args)
|
489
|
-
obj.
|
498
|
+
obj.__send__(name, *args)
|
490
499
|
end
|
491
500
|
end
|
492
501
|
env.instance_eval(&block)
|
data/test/test_pattern-match.rb
CHANGED
@@ -38,17 +38,61 @@ class TestPatternMatch < Test::Unit::TestCase
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_variable_shadowing
|
41
|
-
skip 'not implemented yet'
|
42
41
|
match(0) {
|
43
42
|
with(a) {
|
44
|
-
|
45
|
-
|
43
|
+
assert_equal(0, a)
|
44
|
+
match([1, 2]) {
|
45
|
+
with(_[a, b]) {
|
46
|
+
assert_equal(1, a)
|
47
|
+
assert_equal(2, b)
|
48
|
+
match([3, 4, 5]) {
|
49
|
+
with(_[a, b, c]) {
|
50
|
+
assert_equal(3, a)
|
51
|
+
assert_equal(4, b)
|
52
|
+
assert_equal(5, c)
|
53
|
+
}
|
54
|
+
}
|
46
55
|
assert_equal(1, a)
|
56
|
+
assert_equal(2, b)
|
57
|
+
assert_raise(NameError) { c }
|
47
58
|
}
|
48
59
|
}
|
49
60
|
assert_equal(0, a)
|
61
|
+
assert_raise(NameError) { b }
|
62
|
+
assert_raise(NameError) { c }
|
50
63
|
}
|
51
64
|
}
|
65
|
+
assert_raise(NameError) { a }
|
66
|
+
assert_raise(NameError) { b }
|
67
|
+
assert_raise(NameError) { c }
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_lexical_scoping(rec_call = false, f = nil)
|
71
|
+
skip 'not supported'
|
72
|
+
unless rec_call
|
73
|
+
match(0) {
|
74
|
+
with(a) {
|
75
|
+
assert_equal(0, a)
|
76
|
+
test_lexical_scoping(true, ->{ a }) {|g|
|
77
|
+
assert_equal(0, a)
|
78
|
+
assert_equal(1, g.())
|
79
|
+
}
|
80
|
+
assert_equal(0, a)
|
81
|
+
}
|
82
|
+
}
|
83
|
+
else
|
84
|
+
assert_raise(NameError) { a }
|
85
|
+
assert_equal(0, f.())
|
86
|
+
match(1) {
|
87
|
+
with(a) {
|
88
|
+
assert_equal(1, a)
|
89
|
+
assert_equal(0, f.())
|
90
|
+
yield ->{ a }
|
91
|
+
assert_equal(1, a)
|
92
|
+
assert_equal(0, f.())
|
93
|
+
}
|
94
|
+
}
|
95
|
+
end
|
52
96
|
end
|
53
97
|
|
54
98
|
def test_uscore
|
@@ -254,6 +298,16 @@ class TestPatternMatch < Test::Unit::TestCase
|
|
254
298
|
assert_equal(1, 2.times.find(&match { with(1) { true } }))
|
255
299
|
end
|
256
300
|
|
301
|
+
def test_extractor_class
|
302
|
+
assert_raise(NotImplementedError) {
|
303
|
+
c = Class.new
|
304
|
+
match(0) {
|
305
|
+
with(c.(a)) {
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
end
|
310
|
+
|
257
311
|
def test_extractor_class_struct
|
258
312
|
s = Struct.new(:a, :b, :c)
|
259
313
|
match(s[0, 1, 2]) {
|
@@ -403,7 +457,7 @@ class TestPatternMatch < Test::Unit::TestCase
|
|
403
457
|
c = Class.new
|
404
458
|
::PatternMatch::NameSpace.module_eval {
|
405
459
|
refine c.singleton_class do
|
406
|
-
def
|
460
|
+
def deconstruct(*)
|
407
461
|
[:c]
|
408
462
|
end
|
409
463
|
end
|
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.1.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-03-
|
12
|
+
date: 2012-03-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &8625920 !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: *8625920
|
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: -900071050850383955
|
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: -900071050850383955
|
70
70
|
requirements: []
|
71
71
|
rubyforge_project:
|
72
72
|
rubygems_version: 1.8.11
|