patternmatching 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +25 -0
- data/README.txt +163 -0
- data/Rakefile +143 -0
- data/examples/enumerable_matching.rb +16 -0
- data/examples/hash_matching.rb +16 -0
- data/examples/matching.rb +19 -0
- data/examples/object_matching.rb +25 -0
- data/examples/partial_style_method.rb +24 -0
- data/examples/partial_style_method2.rb +25 -0
- data/lib/patternmatching/pattern.rb +296 -0
- data/lib/patternmatching/version.rb +9 -0
- data/lib/patternmatching.rb +5 -0
- data/scripts/makemanifest.rb +20 -0
- data/scripts/txt2html +67 -0
- data/setup.rb +1585 -0
- data/spec/patternmatching_spec.rb +162 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +1 -0
- data/website/index.html +231 -0
- data/website/index.txt +163 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +129 -0
- data/website/template.rhtml +48 -0
- metadata +75 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require 'patternmatching'
|
3
|
+
|
4
|
+
class CalcM
|
5
|
+
# At first, extends with the module
|
6
|
+
extend PatternMatching
|
7
|
+
|
8
|
+
# def calcm(o), as 3 partial styles
|
9
|
+
func(:calcm).seems as {plus(:left, :right)} do
|
10
|
+
calcm(left) + calcm(right)
|
11
|
+
end
|
12
|
+
func(:calcm).seems as {mul(:left, :right)} do
|
13
|
+
calcm(left) * calcm(right)
|
14
|
+
end
|
15
|
+
func(:calcm).seems as {:value} do
|
16
|
+
value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CalcX
|
21
|
+
extend PatternMatching
|
22
|
+
|
23
|
+
func(:calcx) do
|
24
|
+
seems as {plus(:left, :right)} do
|
25
|
+
calcx(left) + calcx(right)
|
26
|
+
end
|
27
|
+
seems as {mul(:left, :right)} do
|
28
|
+
calcx(left) * calcx(right)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
func(:calcx).seems as {:value} do
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Person
|
37
|
+
def initialize(name, age)
|
38
|
+
@name = name
|
39
|
+
@age = age
|
40
|
+
end
|
41
|
+
attr :name
|
42
|
+
attr :age
|
43
|
+
end
|
44
|
+
|
45
|
+
include PatternMatching
|
46
|
+
def calc(code)
|
47
|
+
make(code) {
|
48
|
+
seems as {plus(:a, :b)} do calc(a) + calc(b) end
|
49
|
+
seems as {mul(:a, :b)} do calc(a) * calc(b) end
|
50
|
+
seems something do code end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "PatternMatching from Example" do
|
55
|
+
it "shuold run calcm as a regular method." do
|
56
|
+
code = PatternMatching.build {plus(mul(100, 100), 200)}
|
57
|
+
ret = CalcM.new.calcm(code)
|
58
|
+
ret.should == 10200
|
59
|
+
end
|
60
|
+
|
61
|
+
it "shuold run calcx as a regular method." do
|
62
|
+
code = PatternMatching.build {plus(mul(100, 100), 200)}
|
63
|
+
ret = CalcX.new.calcx(code)
|
64
|
+
ret.should == 10200
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should run calc as a regular function." do
|
68
|
+
code = PatternMatching.build {plus(mul(100, 100), 200)}
|
69
|
+
ret = calc(code)
|
70
|
+
ret.should == 10200
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should look Enumerable pattern." do
|
74
|
+
is = build { exact([1,2,3,4,5]) }
|
75
|
+
result = make is do
|
76
|
+
seems as {exact([:a,:b,:c])} do # not match
|
77
|
+
a.to_s + " and " + b.to_s + " and" + c.to_s
|
78
|
+
end
|
79
|
+
seems as {exact([:a,:b, _!(:c)])} do
|
80
|
+
a.to_s + ", " + b.to_s + " and " + c.to_s
|
81
|
+
end
|
82
|
+
seems something do
|
83
|
+
"not matched"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
result.should == "1, 2 and 345"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should look Just Enumerable pattern." do
|
90
|
+
is = build { exact([1,2,3,4,5]) }
|
91
|
+
result = make is do
|
92
|
+
seems as {exact([:a,:b,:c])} do # not match
|
93
|
+
a.to_s + " and " + b.to_s + " and" + c.to_s
|
94
|
+
end
|
95
|
+
seems as {exact([:a,:b, :c, :d, :e])} do
|
96
|
+
a.to_s + ", " + b.to_s + ", " + c.to_s + ", " + d.to_s + ", " + e.to_s
|
97
|
+
end
|
98
|
+
seems something do
|
99
|
+
"not matched"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
result.should == "1, 2, 3, 4, 5"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should look Hash pattern." do
|
106
|
+
dict = build { {:name => "Taro", :age => 5} }
|
107
|
+
result = make dict do
|
108
|
+
seems as {{:name => :name}} do
|
109
|
+
"He is " + name
|
110
|
+
end
|
111
|
+
seems something do
|
112
|
+
"no name"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
result.should == "He is Taro"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should look non-Hash pattern." do
|
119
|
+
person = Person.new("Jiro", 3)
|
120
|
+
result = make person do
|
121
|
+
seems as {{:name => :name}} do
|
122
|
+
"He is " + name
|
123
|
+
end
|
124
|
+
seems something do
|
125
|
+
"no name"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
result.should == "He is Jiro"
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should look nested pattern." do
|
132
|
+
code = build {plus(mul(100, 120, 300), plus(200, 150))}
|
133
|
+
result = make code do
|
134
|
+
seems as {plus(plus(:a, :b, _), plus(:c, _))} do # not match
|
135
|
+
[a, b, c]
|
136
|
+
end
|
137
|
+
seems as {plus(mul(_, :a, _), plus(:b, _))} do
|
138
|
+
[a, b]
|
139
|
+
end
|
140
|
+
seems something do
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
result.should == [120, 200]
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should look wildcard node pattern." do
|
148
|
+
code = build {plus(mul(100, 120, 300), plus(200, 150))}
|
149
|
+
result = make code do
|
150
|
+
seems as {_(_(_, _, :a), mul(_, :b))} do # not match
|
151
|
+
[a, b]
|
152
|
+
end
|
153
|
+
seems as {plus(_(_, :a, _), _(:b, _))} do
|
154
|
+
[a, b]
|
155
|
+
end
|
156
|
+
seems something do
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
result.should == [120, 200]
|
161
|
+
end
|
162
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec'
|
data/website/index.html
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>
|
8
|
+
PatternMatching module
|
9
|
+
</title>
|
10
|
+
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
+
<style>
|
12
|
+
|
13
|
+
</style>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.onload = function() {
|
16
|
+
settings = {
|
17
|
+
tl: { radius: 10 },
|
18
|
+
tr: { radius: 10 },
|
19
|
+
bl: { radius: 10 },
|
20
|
+
br: { radius: 10 },
|
21
|
+
antiAlias: true,
|
22
|
+
autoPad: true,
|
23
|
+
validTags: ["div"]
|
24
|
+
}
|
25
|
+
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
+
versionBox.applyCornersToAll();
|
27
|
+
}
|
28
|
+
</script>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="main">
|
32
|
+
|
33
|
+
<h1>PatternMatching module</h1>
|
34
|
+
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/patternmatching"; return false'>
|
35
|
+
Get Version
|
36
|
+
<a href="http://rubyforge.org/projects/patternmatching" class="numbers">0.1.0</a>
|
37
|
+
</div>
|
38
|
+
<h1>→ ‘patternmatching’</h1>
|
39
|
+
|
40
|
+
|
41
|
+
<h2>What</h2>
|
42
|
+
|
43
|
+
|
44
|
+
Provides a pure ruby module that:
|
45
|
+
<ul>
|
46
|
+
<li>can build structured objects easily</li>
|
47
|
+
<li>can enable pattern match of objects</li>
|
48
|
+
<li>can define method as a partial function style</li>
|
49
|
+
</ul>
|
50
|
+
|
51
|
+
|
52
|
+
<h2>Installing</h2>
|
53
|
+
|
54
|
+
|
55
|
+
<pre syntax="ruby">sudo gem install patternmatching</pre>
|
56
|
+
|
57
|
+
<h2>The basics</h2>
|
58
|
+
|
59
|
+
|
60
|
+
<p>This module provides methods for tree pattern matching features.</p>
|
61
|
+
|
62
|
+
|
63
|
+
<ul>
|
64
|
+
<li>For detail, see Wikipedia: <a href="http://en.wikipedia.org/wiki/Pattern_matching">Pattern matching</a></li>
|
65
|
+
<li>Syntax based on meta-programming, like “rspec”, and so on.</li>
|
66
|
+
</ul>
|
67
|
+
|
68
|
+
|
69
|
+
<p>Note: Default equivalence used in structured pattern matching is
|
70
|
+
based on “pattern === data”, so “foo(Numeric)” matches with “foo(100)”</p>
|
71
|
+
|
72
|
+
|
73
|
+
<p>Note: Not thread safe now.</p>
|
74
|
+
|
75
|
+
|
76
|
+
<h2>Demonstration of usage</h2>
|
77
|
+
|
78
|
+
|
79
|
+
<h3>Pattern matching expression</h3>
|
80
|
+
<pre>
|
81
|
+
require "patternmatching"
|
82
|
+
|
83
|
+
# For DSL style code, include PatternMatching
|
84
|
+
include PatternMatching
|
85
|
+
|
86
|
+
# match example
|
87
|
+
def calc(code)
|
88
|
+
make(code) {
|
89
|
+
seems as {plus(:x, :y)} do calc(x) + calc(y) end
|
90
|
+
seems as {mul(:x, :y)} do calc(x) * calc(y) end
|
91
|
+
seems something do code end
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
code = build {plus(mul(100, 100), 200)}
|
96
|
+
p calc(code) #=> 10200
|
97
|
+
</pre>
|
98
|
+
|
99
|
+
<h3>Partial style method</h3>
|
100
|
+
<pre>
|
101
|
+
require "patternmatching"
|
102
|
+
|
103
|
+
# Structured data builder
|
104
|
+
code = PatternMatching.build {plus(mul(100, 100), 200)}
|
105
|
+
|
106
|
+
# Partial style method example
|
107
|
+
class Calc
|
108
|
+
# At first, extends with the module
|
109
|
+
extend PatternMatching
|
110
|
+
|
111
|
+
# def calcm(o), as 3 partial styles
|
112
|
+
func(:calcm).seems as {plus(:x, :y)} do
|
113
|
+
calcm(x) + calcm(y)
|
114
|
+
end
|
115
|
+
func(:calcm).seems as {mul(:x, :y)} do
|
116
|
+
calcm(x) * calcm(y)
|
117
|
+
end
|
118
|
+
func(:calcm).seems as {:value} do
|
119
|
+
value
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# use as standard method
|
124
|
+
p Calc.new.calcm(code) #=> 10200
|
125
|
+
</pre>
|
126
|
+
|
127
|
+
<h3>Array/Enumerable pattern</h3>
|
128
|
+
<pre>
|
129
|
+
require "patternmatching"
|
130
|
+
|
131
|
+
include PatternMatching
|
132
|
+
|
133
|
+
# Example for matching Enumerable
|
134
|
+
is = build { exact([1,2,3,4,5]) }
|
135
|
+
make is do
|
136
|
+
# _! matches rest of lists
|
137
|
+
seems as {exact([:a,:b, _!(:c)])} do
|
138
|
+
puts a.to_s + ", " + b.to_s + " and " + c.to_s
|
139
|
+
end
|
140
|
+
seems something do
|
141
|
+
puts "not matched"
|
142
|
+
end
|
143
|
+
end # => "1, 2, and 345"
|
144
|
+
</pre>
|
145
|
+
|
146
|
+
<h3>Hash pattern</h3>
|
147
|
+
<pre>
|
148
|
+
require "patternmatching"
|
149
|
+
|
150
|
+
include PatternMatching
|
151
|
+
|
152
|
+
# Example for matching Hash
|
153
|
+
dict = build { {:name => "Taro", :age => 5} }
|
154
|
+
make dict do
|
155
|
+
seems as {{:name => :name}} do
|
156
|
+
puts "He is " + name
|
157
|
+
end
|
158
|
+
seems something do
|
159
|
+
puts "no name"
|
160
|
+
end
|
161
|
+
end # => "He is Taro"
|
162
|
+
</pre>
|
163
|
+
|
164
|
+
<h3>Non-Hash/Object pattern</h3>
|
165
|
+
<pre>
|
166
|
+
require "patternmatching"
|
167
|
+
|
168
|
+
include PatternMatching
|
169
|
+
|
170
|
+
class Person
|
171
|
+
def initialize(name, age)
|
172
|
+
@name = name
|
173
|
+
@age = age
|
174
|
+
end
|
175
|
+
attr :name
|
176
|
+
attr :age
|
177
|
+
end
|
178
|
+
|
179
|
+
# Example for matching Object except Hash
|
180
|
+
person = Person.new("Jiro", 3)
|
181
|
+
make person do
|
182
|
+
seems as {{:name => :name}} do
|
183
|
+
puts "He is " + name
|
184
|
+
end
|
185
|
+
seems something do
|
186
|
+
puts "no name"
|
187
|
+
end
|
188
|
+
end # => "He is Jiro"
|
189
|
+
</pre>
|
190
|
+
|
191
|
+
<h2>Forum</h2>
|
192
|
+
|
193
|
+
|
194
|
+
<h2>How to submit patches</h2>
|
195
|
+
|
196
|
+
|
197
|
+
<p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people’s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
|
198
|
+
|
199
|
+
|
200
|
+
<p>The trunk repository is <code>svn://rubyforge.org/var/svn/patternmatching/trunk</code> for anonymous access.</p>
|
201
|
+
|
202
|
+
|
203
|
+
<h2>License</h2>
|
204
|
+
|
205
|
+
|
206
|
+
<p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
|
207
|
+
|
208
|
+
|
209
|
+
<h2>Link</h2>
|
210
|
+
|
211
|
+
|
212
|
+
<ul>
|
213
|
+
<li><a href="http://patternmatching.rubyforge.org/">Web Site</a></li>
|
214
|
+
<li><a href="http://rubyforge.org/projects/patternmatching/">Project Page</a></li>
|
215
|
+
</ul>
|
216
|
+
|
217
|
+
|
218
|
+
<h2>Contact</h2>
|
219
|
+
|
220
|
+
|
221
|
+
<p>Comments are welcome. Send an email to <a href="mailto:bellbind@gmail.com"><span class="caps">ICHIYAMA</span> Ryoichi</a>. <a href="http://d.hatena.ne.jp/bellbind">My blog</a> (written in Japanese) could be help you.</p>
|
222
|
+
<p class="coda">
|
223
|
+
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 4th June 2007<br>
|
224
|
+
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
225
|
+
</p>
|
226
|
+
</div>
|
227
|
+
|
228
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
229
|
+
|
230
|
+
</body>
|
231
|
+
</html>
|
data/website/index.txt
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
h1. PatternMatching module
|
2
|
+
|
3
|
+
h1. → 'patternmatching'
|
4
|
+
|
5
|
+
h2. What
|
6
|
+
|
7
|
+
Provides a pure ruby module that:
|
8
|
+
* can build structured objects easily
|
9
|
+
* can enable pattern match of objects
|
10
|
+
* can define method as a partial function style
|
11
|
+
|
12
|
+
h2. Installing
|
13
|
+
|
14
|
+
<pre syntax="ruby">sudo gem install patternmatching</pre>
|
15
|
+
|
16
|
+
h2. The basics
|
17
|
+
|
18
|
+
This module provides methods for tree pattern matching features.
|
19
|
+
|
20
|
+
* For detail, see Wikipedia: "Pattern matching":http://en.wikipedia.org/wiki/Pattern_matching
|
21
|
+
* Syntax based on meta-programming, like "rspec", and so on.
|
22
|
+
|
23
|
+
Note: Default equivalence used in structured pattern matching is
|
24
|
+
based on "pattern === data", so "foo(Numeric)" matches with "foo(100)"
|
25
|
+
|
26
|
+
Note: Not thread safe now.
|
27
|
+
|
28
|
+
h2. Demonstration of usage
|
29
|
+
|
30
|
+
<h3>Pattern matching expression</h3>
|
31
|
+
<pre>
|
32
|
+
require "patternmatching"
|
33
|
+
|
34
|
+
# For DSL style code, include PatternMatching
|
35
|
+
include PatternMatching
|
36
|
+
|
37
|
+
# match example
|
38
|
+
def calc(code)
|
39
|
+
make(code) {
|
40
|
+
seems as {plus(:x, :y)} do calc(x) + calc(y) end
|
41
|
+
seems as {mul(:x, :y)} do calc(x) * calc(y) end
|
42
|
+
seems something do code end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
code = build {plus(mul(100, 100), 200)}
|
47
|
+
p calc(code) #=> 10200
|
48
|
+
</pre>
|
49
|
+
|
50
|
+
<h3>Partial style method</h3>
|
51
|
+
<pre>
|
52
|
+
require "patternmatching"
|
53
|
+
|
54
|
+
# Structured data builder
|
55
|
+
code = PatternMatching.build {plus(mul(100, 100), 200)}
|
56
|
+
|
57
|
+
# Partial style method example
|
58
|
+
class Calc
|
59
|
+
# At first, extends with the module
|
60
|
+
extend PatternMatching
|
61
|
+
|
62
|
+
# def calcm(o), as 3 partial styles
|
63
|
+
func(:calcm).seems as {plus(:x, :y)} do
|
64
|
+
calcm(x) + calcm(y)
|
65
|
+
end
|
66
|
+
func(:calcm).seems as {mul(:x, :y)} do
|
67
|
+
calcm(x) * calcm(y)
|
68
|
+
end
|
69
|
+
func(:calcm).seems as {:value} do
|
70
|
+
value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# use as standard method
|
75
|
+
p Calc.new.calcm(code) #=> 10200
|
76
|
+
</pre>
|
77
|
+
|
78
|
+
<h3>Array/Enumerable pattern</h3>
|
79
|
+
<pre>
|
80
|
+
require "patternmatching"
|
81
|
+
|
82
|
+
include PatternMatching
|
83
|
+
|
84
|
+
# Example for matching Enumerable
|
85
|
+
is = build { exact([1,2,3,4,5]) }
|
86
|
+
make is do
|
87
|
+
# _! matches rest of lists
|
88
|
+
seems as {exact([:a,:b, _!(:c)])} do
|
89
|
+
puts a.to_s + ", " + b.to_s + " and " + c.to_s
|
90
|
+
end
|
91
|
+
seems something do
|
92
|
+
puts "not matched"
|
93
|
+
end
|
94
|
+
end # => "1, 2, and 345"
|
95
|
+
</pre>
|
96
|
+
|
97
|
+
<h3>Hash pattern</h3>
|
98
|
+
<pre>
|
99
|
+
require "patternmatching"
|
100
|
+
|
101
|
+
include PatternMatching
|
102
|
+
|
103
|
+
# Example for matching Hash
|
104
|
+
dict = build { {:name => "Taro", :age => 5} }
|
105
|
+
make dict do
|
106
|
+
seems as {{:name => :name}} do
|
107
|
+
puts "He is " + name
|
108
|
+
end
|
109
|
+
seems something do
|
110
|
+
puts "no name"
|
111
|
+
end
|
112
|
+
end # => "He is Taro"
|
113
|
+
</pre>
|
114
|
+
|
115
|
+
<h3>Non-Hash/Object pattern</h3>
|
116
|
+
<pre>
|
117
|
+
require "patternmatching"
|
118
|
+
|
119
|
+
include PatternMatching
|
120
|
+
|
121
|
+
class Person
|
122
|
+
def initialize(name, age)
|
123
|
+
@name = name
|
124
|
+
@age = age
|
125
|
+
end
|
126
|
+
attr :name
|
127
|
+
attr :age
|
128
|
+
end
|
129
|
+
|
130
|
+
# Example for matching Object except Hash
|
131
|
+
person = Person.new("Jiro", 3)
|
132
|
+
make person do
|
133
|
+
seems as {{:name => :name}} do
|
134
|
+
puts "He is " + name
|
135
|
+
end
|
136
|
+
seems something do
|
137
|
+
puts "no name"
|
138
|
+
end
|
139
|
+
end # => "He is Jiro"
|
140
|
+
</pre>
|
141
|
+
|
142
|
+
h2. Forum
|
143
|
+
|
144
|
+
|
145
|
+
h2. How to submit patches
|
146
|
+
|
147
|
+
Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
|
148
|
+
|
149
|
+
The trunk repository is <code>svn://rubyforge.org/var/svn/patternmatching/trunk</code> for anonymous access.
|
150
|
+
|
151
|
+
h2. License
|
152
|
+
|
153
|
+
This code is free to use under the terms of the MIT license.
|
154
|
+
|
155
|
+
h2. Link
|
156
|
+
|
157
|
+
* "Web Site":http://patternmatching.rubyforge.org/
|
158
|
+
* "Project Page":http://rubyforge.org/projects/patternmatching/
|
159
|
+
|
160
|
+
h2. Contact
|
161
|
+
|
162
|
+
Comments are welcome. Send an email to "ICHIYAMA Ryoichi":mailto:bellbind@gmail.com. "My blog":http://d.hatena.ne.jp/bellbind (written in Japanese) could be help you.
|
163
|
+
|