multimethod 0.0.1

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.
Files changed (55) hide show
  1. data/.svn/README.txt +2 -0
  2. data/.svn/empty-file +0 -0
  3. data/.svn/entries +68 -0
  4. data/.svn/format +1 -0
  5. data/.svn/text-base/ChangeLog.svn-base +3 -0
  6. data/.svn/text-base/Manifest.txt.svn-base +54 -0
  7. data/.svn/text-base/README.txt.svn-base +40 -0
  8. data/.svn/text-base/Rakefile.svn-base +132 -0
  9. data/.svn/text-base/Releases.txt.svn-base +7 -0
  10. data/ChangeLog +3 -0
  11. data/Manifest.txt +54 -0
  12. data/README.txt +40 -0
  13. data/Rakefile +132 -0
  14. data/Releases.txt +7 -0
  15. data/examples/.svn/README.txt +2 -0
  16. data/examples/.svn/empty-file +0 -0
  17. data/examples/.svn/entries +22 -0
  18. data/examples/.svn/format +1 -0
  19. data/examples/.svn/props/ex1.rb.svn-work +5 -0
  20. data/examples/ex1.rb +26 -0
  21. data/lib/.svn/README.txt +2 -0
  22. data/lib/.svn/empty-file +0 -0
  23. data/lib/.svn/entries +24 -0
  24. data/lib/.svn/format +1 -0
  25. data/lib/.svn/text-base/multimethod.rb.svn-base +8 -0
  26. data/lib/multimethod.rb +8 -0
  27. data/lib/multimethod/.svn/README.txt +2 -0
  28. data/lib/multimethod/.svn/empty-file +0 -0
  29. data/lib/multimethod/.svn/entries +53 -0
  30. data/lib/multimethod/.svn/format +1 -0
  31. data/lib/multimethod/.svn/text-base/core_extensions.rb.svn-base +38 -0
  32. data/lib/multimethod/.svn/text-base/method.rb.svn-base +232 -0
  33. data/lib/multimethod/.svn/text-base/multimethod.rb.svn-base +171 -0
  34. data/lib/multimethod/.svn/text-base/parameter.rb.svn-base +64 -0
  35. data/lib/multimethod/.svn/text-base/table.rb.svn-base +99 -0
  36. data/lib/multimethod/core_extensions.rb +38 -0
  37. data/lib/multimethod/method.rb +232 -0
  38. data/lib/multimethod/multimethod.rb +171 -0
  39. data/lib/multimethod/parameter.rb +64 -0
  40. data/lib/multimethod/table.rb +99 -0
  41. data/test/.svn/README.txt +2 -0
  42. data/test/.svn/empty-file +0 -0
  43. data/test/.svn/entries +53 -0
  44. data/test/.svn/format +1 -0
  45. data/test/.svn/text-base/method_test.rb.svn-base +89 -0
  46. data/test/.svn/text-base/multimethod_test.rb.svn-base +92 -0
  47. data/test/.svn/text-base/parameter_test.rb.svn-base +31 -0
  48. data/test/.svn/text-base/test_base.rb.svn-base +25 -0
  49. data/test/.svn/text-base/usage_test.rb.svn-base +146 -0
  50. data/test/method_test.rb +89 -0
  51. data/test/multimethod_test.rb +92 -0
  52. data/test/parameter_test.rb +31 -0
  53. data/test/test_base.rb +25 -0
  54. data/test/usage_test.rb +146 -0
  55. metadata +108 -0
@@ -0,0 +1,92 @@
1
+ require 'test_base'
2
+
3
+ module Multimethod
4
+
5
+ class MethodTest < TestBase
6
+
7
+ class A < Object; end
8
+ class B < A; end
9
+ class C < Object; end
10
+ class D < B; end
11
+ class E < A; end
12
+
13
+ def setup
14
+ super
15
+ end
16
+
17
+ def test_score
18
+ # Make some argument lists.
19
+ types = [ A, B, C, D, E ]
20
+ a = { }
21
+ c = { }
22
+ types.each do |t1|
23
+ n1 = t1.name.clone
24
+ n1.sub!(/^.*::/, '')
25
+ n1 = n1[0..0]
26
+ types.each do |t2|
27
+ n2 = t2.name.clone
28
+ n2.sub!(/^.*::/, '')
29
+ n2 = n2[0..0]
30
+
31
+ symbol = "#{n1.downcase}_#{n2.downcase}".intern
32
+ a[symbol] = [ 1, t1.new, t2.new ]
33
+ c[symbol] = a[symbol].collect{|x| x.class}
34
+ end
35
+ end
36
+
37
+ rs = Parameter::RESTARG_SCORE
38
+
39
+ assert_not_nil m1 = Method.new(Object, :m, [ A, :x, A, :y ])
40
+ assert_equal 3, m1.min_args
41
+ assert_equal 3, m1.max_args
42
+
43
+ assert_not_nil m2 = Method.new(Object, :m, [ B, :x, A, :y ])
44
+ assert_equal 3, m2.min_args
45
+ assert_equal 3, m2.max_args
46
+
47
+ assert_not_nil m3 = Method.new(Object, :m, [ C, :x, '*rest' ])
48
+ assert_equal 2, m3.min_args
49
+ assert_equal nil, m3.max_args
50
+ assert_not_nil m3.restarg
51
+
52
+ assert_not_nil m4 = Method.new(Object, :m, [ D, :x, :y ])
53
+ assert_equal 3, m4.min_args
54
+ assert_equal 3, m4.max_args
55
+
56
+ assert_not_nil m5 = Method.new(Object, :m, [ E, :y, :y ])
57
+ assert_equal 3, m4.min_args
58
+ assert_equal 3, m4.max_args
59
+
60
+ # 5 == 1.class.ancestors.index(Object)
61
+ assert_equal [ 5, 0, 0 ] , m1.score(c[:a_a])
62
+ assert_equal [ 5, 0, 1 ] , m1.score(c[:a_b])
63
+ assert_equal nil , m1.score(c[:a_c])
64
+ assert_equal [ 5, 1, 1 ] , m1.score(c[:b_b])
65
+ assert_equal nil , m1.score(c[:c_a])
66
+ assert_equal [ 5, 1, 2 ] , m1.score(c[:b_d])
67
+
68
+ assert_equal nil , m3.score(c[:a_a])
69
+ assert_equal nil , m3.score(c[:a_b])
70
+ assert_equal nil , m3.score(c[:b_b])
71
+ assert_equal [ 5, 0, rs ] , m3.score(c[:c_a])
72
+ assert_equal [ 5, 0, rs ] , m3.score(c[:c_c])
73
+
74
+ # Create a multimethod for later.
75
+ assert_not_nil mm = Multimethod.new(:test)
76
+ mm.add_method(m1)
77
+ mm.add_method(m2)
78
+ mm.add_method(m3)
79
+ mm.add_method(m4)
80
+
81
+ # Check method lookup.
82
+ assert_equal m1 , mm.lookup_method_(c[:a_a])
83
+ assert_equal m2 , mm.lookup_method_(c[:b_a])
84
+ assert_equal m2 , mm.lookup_method_(c[:b_b])
85
+
86
+ mm
87
+ end
88
+
89
+ end # class
90
+
91
+ end # module
92
+
@@ -0,0 +1,31 @@
1
+ require 'test_base'
2
+
3
+ module Multimethod
4
+
5
+ class ParameterTest < TestBase
6
+
7
+ class A < Object; end
8
+ class B < A; end
9
+ class C < Object; end
10
+ class D < B; end
11
+
12
+ def setup
13
+ super
14
+ end
15
+
16
+ def test_score
17
+ pA = Parameter.new(:a, A)
18
+ assert_equal 0, pA.score(A)
19
+ assert_equal 1, pA.score(B)
20
+ assert_equal nil, pA.score(C)
21
+ assert_equal 2, pA.score(D)
22
+
23
+ pB = Parameter.new(:b, B)
24
+ assert_equal nil, pB.score(A)
25
+ assert_equal 0, pB.score(B)
26
+ assert_equal nil, pB.score(C)
27
+ assert_equal 1, pB.score(D)
28
+ end
29
+ end # class
30
+
31
+ end # module
@@ -0,0 +1,25 @@
1
+ require 'test/unit'
2
+ require 'multimethod'
3
+
4
+ module Multimethod
5
+
6
+ class TestBase < Test::Unit::TestCase
7
+ def setup
8
+ super
9
+ end
10
+
11
+ # Avoid "No test were specified" error.
12
+ def test_foo
13
+ assert true
14
+ end
15
+
16
+ # Helpers.
17
+ def assert_equal_float(x, y, eps = 1.0e-8)
18
+ d = (x * eps).abs
19
+ assert (x - d) <= y
20
+ assert y <= (x + d)
21
+ end
22
+
23
+ end # class
24
+
25
+ end # module
@@ -0,0 +1,146 @@
1
+ require 'test_base'
2
+
3
+
4
+ class A < Object
5
+ multimethod %q{
6
+ def foo(x)
7
+ x = "A#foo(x) : (#{x.class.name})"
8
+ x
9
+ end
10
+ }
11
+
12
+ multimethod %q{
13
+ def foo(A x)
14
+ x = "A#foo(A x) : (#{x.class.name})"
15
+ x
16
+ end
17
+ }
18
+
19
+ multimethod %q{
20
+ def foo(B x)
21
+ x = "A#foo(B x) : (#{x.class.name})"
22
+ x
23
+ end
24
+ }
25
+
26
+ end
27
+
28
+ class B < A
29
+ multimethod %q{
30
+ def foo(B x)
31
+ x = "B#foo(B x) : (#{x.class.name})"
32
+ x
33
+ end
34
+ }
35
+
36
+ multimethod %q{
37
+ def foo(Comparable x)
38
+ x = "B#foo(Comparable x) : (#{x.class.name})"
39
+ x
40
+ end
41
+ }
42
+
43
+
44
+ end
45
+
46
+ class C < Object
47
+ include Comparable
48
+ end
49
+
50
+ class D < B
51
+ # Variadic
52
+ multimethod %q{
53
+ def bar(x)
54
+ x = "D#bar(x) : (#{x.class.name})"
55
+ x
56
+ end
57
+ }
58
+
59
+ multimethod %q{
60
+ def bar(*rest)
61
+ x = "D#bar(*rest) : (#{rest.inspect})"
62
+ x
63
+ end
64
+ }
65
+
66
+ multimethod %q{
67
+ def bar(x, y)
68
+ x = "D#bar(x, y) : (#{x.class.name}, #{y.class.name})"
69
+ x
70
+ end
71
+ }
72
+
73
+ multimethod %q{
74
+ def bar(x, y, A a)
75
+ x = "D#bar(x, y, A a) : (#{x.class.name}, #{y.class.name}, #{a.class.name})"
76
+ x
77
+ end
78
+ }
79
+
80
+ multimethod %q{
81
+ def bar(x, y, *rest)
82
+ x = "D#bar(x, y, *rest) : (#{x.class.name}, #{y.class.name}, #{rest.inspect})"
83
+ x
84
+ end
85
+ }
86
+
87
+ end # class D
88
+
89
+ class E < A
90
+ end
91
+
92
+
93
+ module Multimethod
94
+
95
+ class UsageTest < TestBase
96
+
97
+ def setup
98
+ super
99
+ end
100
+
101
+ def test_call
102
+ a = A.new
103
+ b = B.new
104
+ c = C.new
105
+ d = D.new
106
+ e = E.new
107
+
108
+ assert_equal 'A#foo(x) : (Fixnum)' , a.foo(1)
109
+ assert_equal 'A#foo(A x) : (A)' , a.foo(a)
110
+ assert_equal 'A#foo(B x) : (B)' , a.foo(b)
111
+ assert_equal 'A#foo(x) : (C)' , a.foo(c)
112
+ assert_equal 'A#foo(B x) : (D)' , a.foo(d)
113
+ assert_equal 'A#foo(A x) : (E)' , a.foo(e)
114
+
115
+ assert_equal 'A#foo(x) : (Symbol)' , b.foo(:x)
116
+ assert_equal 'B#foo(Comparable x) : (Fixnum)' , b.foo(1)
117
+ assert_equal 'A#foo(A x) : (A)' , b.foo(a)
118
+ assert_equal 'B#foo(B x) : (B)' , b.foo(b)
119
+ assert_equal 'B#foo(Comparable x) : (C)' , b.foo(c)
120
+ assert_equal 'B#foo(B x) : (D)' , b.foo(d)
121
+ assert_equal 'A#foo(A x) : (E)' , b.foo(e)
122
+ end
123
+
124
+ def test_variadic
125
+ a = A.new
126
+ d = D.new
127
+
128
+ assert_equal 'D#bar(*rest) : ([])',
129
+ d.bar()
130
+
131
+ assert_equal 'D#bar(x) : (Fixnum)',
132
+ d.bar(1)
133
+
134
+ assert_equal 'D#bar(x, y) : (Fixnum, String)' ,
135
+ d.bar(1, 'a')
136
+
137
+ assert_equal 'D#bar(x, y, A a) : (Fixnum, String, A)' ,
138
+ d.bar(1, 'a', a)
139
+
140
+ assert_equal 'D#bar(x, y, *rest) : (Fixnum, String, [3])' ,
141
+ d.bar(1, 'a', 3)
142
+ end
143
+
144
+ end # class
145
+
146
+ end # module
@@ -0,0 +1,89 @@
1
+ require 'test_base'
2
+
3
+ module Multimethod
4
+
5
+ class MethodTest < TestBase
6
+
7
+ class A < Object; end
8
+ class B < A; end
9
+ class C < Object; end
10
+ class D < B; end
11
+
12
+ def setup
13
+ super
14
+ end
15
+
16
+ def test_scan_parameter
17
+ assert_not_nil m1 = Method.new(Object, :m, [ A, :a, B, :b, :c, '*d' ])
18
+
19
+ assert_equal 5, m1.parameter.size
20
+
21
+ i = -1
22
+
23
+ i = i + 1
24
+ assert_equal :self, m1.parameter[i].name
25
+ assert_equal Object, m1.parameter[i].type
26
+ assert ! m1.parameter[i].restarg
27
+
28
+ i = i + 1
29
+ assert_equal :a, m1.parameter[i].name
30
+ assert_equal A, m1.parameter[i].type
31
+ assert ! m1.parameter[i].restarg
32
+
33
+ i = i + 1
34
+ assert_equal :b, m1.parameter[i].name
35
+ assert_equal B, m1.parameter[i].type
36
+ assert ! m1.parameter[i].restarg
37
+
38
+ i = i + 1
39
+ assert_equal :c, m1.parameter[i].name
40
+ assert_equal Kernel, m1.parameter[i].type
41
+ assert ! m1.parameter[i].restarg
42
+
43
+ i = i + 1
44
+ assert_equal :d, m1.parameter[i].name
45
+ assert_equal Kernel, m1.parameter[i].type
46
+ assert m1.parameter[i].restarg
47
+
48
+ m1
49
+ end
50
+
51
+ def test_scan_parameter_string
52
+ assert_not_nil m1 = Method.new(Object, :m, 'A a, B b, c = nil, *d')
53
+
54
+ assert_equal 5, m1.parameter.size
55
+
56
+ i = -1
57
+
58
+ i = i + 1
59
+ assert_equal :self, m1.parameter[i].name
60
+ assert_equal Object, m1.parameter[i].type
61
+ assert ! m1.parameter[i].restarg
62
+
63
+ i = i + 1
64
+ assert_equal :a, m1.parameter[i].name
65
+ assert_equal 'A', m1.parameter[i].type
66
+ assert ! m1.parameter[i].restarg
67
+
68
+ i = i + 1
69
+ assert_equal :b, m1.parameter[i].name
70
+ assert_equal 'B', m1.parameter[i].type
71
+ assert ! m1.parameter[i].restarg
72
+
73
+ i = i + 1
74
+ assert_equal :c, m1.parameter[i].name
75
+ assert_equal Kernel, m1.parameter[i].type
76
+ assert ! m1.parameter[i].restarg
77
+
78
+ i = i + 1
79
+ assert_equal :d, m1.parameter[i].name
80
+ assert_equal Kernel, m1.parameter[i].type
81
+ assert m1.parameter[i].restarg
82
+
83
+ m1
84
+ end
85
+
86
+ end # class
87
+
88
+ end # module
89
+
@@ -0,0 +1,92 @@
1
+ require 'test_base'
2
+
3
+ module Multimethod
4
+
5
+ class MethodTest < TestBase
6
+
7
+ class A < Object; end
8
+ class B < A; end
9
+ class C < Object; end
10
+ class D < B; end
11
+ class E < A; end
12
+
13
+ def setup
14
+ super
15
+ end
16
+
17
+ def test_score
18
+ # Make some argument lists.
19
+ types = [ A, B, C, D, E ]
20
+ a = { }
21
+ c = { }
22
+ types.each do |t1|
23
+ n1 = t1.name.clone
24
+ n1.sub!(/^.*::/, '')
25
+ n1 = n1[0..0]
26
+ types.each do |t2|
27
+ n2 = t2.name.clone
28
+ n2.sub!(/^.*::/, '')
29
+ n2 = n2[0..0]
30
+
31
+ symbol = "#{n1.downcase}_#{n2.downcase}".intern
32
+ a[symbol] = [ 1, t1.new, t2.new ]
33
+ c[symbol] = a[symbol].collect{|x| x.class}
34
+ end
35
+ end
36
+
37
+ rs = Parameter::RESTARG_SCORE
38
+
39
+ assert_not_nil m1 = Method.new(Object, :m, [ A, :x, A, :y ])
40
+ assert_equal 3, m1.min_args
41
+ assert_equal 3, m1.max_args
42
+
43
+ assert_not_nil m2 = Method.new(Object, :m, [ B, :x, A, :y ])
44
+ assert_equal 3, m2.min_args
45
+ assert_equal 3, m2.max_args
46
+
47
+ assert_not_nil m3 = Method.new(Object, :m, [ C, :x, '*rest' ])
48
+ assert_equal 2, m3.min_args
49
+ assert_equal nil, m3.max_args
50
+ assert_not_nil m3.restarg
51
+
52
+ assert_not_nil m4 = Method.new(Object, :m, [ D, :x, :y ])
53
+ assert_equal 3, m4.min_args
54
+ assert_equal 3, m4.max_args
55
+
56
+ assert_not_nil m5 = Method.new(Object, :m, [ E, :y, :y ])
57
+ assert_equal 3, m4.min_args
58
+ assert_equal 3, m4.max_args
59
+
60
+ # 5 == 1.class.ancestors.index(Object)
61
+ assert_equal [ 5, 0, 0 ] , m1.score(c[:a_a])
62
+ assert_equal [ 5, 0, 1 ] , m1.score(c[:a_b])
63
+ assert_equal nil , m1.score(c[:a_c])
64
+ assert_equal [ 5, 1, 1 ] , m1.score(c[:b_b])
65
+ assert_equal nil , m1.score(c[:c_a])
66
+ assert_equal [ 5, 1, 2 ] , m1.score(c[:b_d])
67
+
68
+ assert_equal nil , m3.score(c[:a_a])
69
+ assert_equal nil , m3.score(c[:a_b])
70
+ assert_equal nil , m3.score(c[:b_b])
71
+ assert_equal [ 5, 0, rs ] , m3.score(c[:c_a])
72
+ assert_equal [ 5, 0, rs ] , m3.score(c[:c_c])
73
+
74
+ # Create a multimethod for later.
75
+ assert_not_nil mm = Multimethod.new(:test)
76
+ mm.add_method(m1)
77
+ mm.add_method(m2)
78
+ mm.add_method(m3)
79
+ mm.add_method(m4)
80
+
81
+ # Check method lookup.
82
+ assert_equal m1 , mm.lookup_method_(c[:a_a])
83
+ assert_equal m2 , mm.lookup_method_(c[:b_a])
84
+ assert_equal m2 , mm.lookup_method_(c[:b_b])
85
+
86
+ mm
87
+ end
88
+
89
+ end # class
90
+
91
+ end # module
92
+