patternmatching 0.1.0

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.
@@ -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
@@ -0,0 +1 @@
1
+ require 'spec'
@@ -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>&#x2192; &#8216;patternmatching&#8217;</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 &#8220;rspec&#8221;, and so on.</li>
66
+ </ul>
67
+
68
+
69
+ <p>Note: Default equivalence used in structured pattern matching is
70
+ based on &#8220;pattern === data&#8221;, so &#8220;foo(Numeric)&#8221; matches with &#8220;foo(100)&#8221;</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) #=&gt; 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) #=&gt; 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 # =&gt; "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 =&gt; "Taro", :age =&gt; 5} }
154
+ make dict do
155
+ seems as {{:name =&gt; :name}} do
156
+ puts "He is " + name
157
+ end
158
+ seems something do
159
+ puts "no name"
160
+ end
161
+ end # =&gt; "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 =&gt; :name}} do
183
+ puts "He is " + name
184
+ end
185
+ seems something do
186
+ puts "no name"
187
+ end
188
+ end # =&gt; "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&#8217;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. &#x2192; '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
+