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 CHANGED
@@ -15,7 +15,89 @@ or
15
15
  $ bundle install --path vendor/bundle
16
16
 
17
17
  == Example
18
- See test/test_pattern-match.rb.
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
@@ -1,3 +1,3 @@
1
1
  module PatternMatch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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 === 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
@@ -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.1
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-03 00:00:00.000000000 Z
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: &8351800 !ruby/object:Gem::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: *8351800
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: 2652740272817572795
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: 2652740272817572795
69
+ hash: 2122497246809249036
70
70
  requirements: []
71
71
  rubyforge_project:
72
72
  rubygems_version: 1.8.11