rewrite 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ desc 'Release the website and new gem version'
2
+ task :deploy => [:check_version, :website, :release] do
3
+ puts "Remember to create SVN tag:"
4
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
5
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
6
+ puts "Suggested comment:"
7
+ puts "Tagging release #{CHANGES}"
8
+ end
9
+
10
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
11
+ task :local_deploy => [:website_generate, :install_gem]
12
+
13
+ task :check_version do
14
+ unless ENV['VERSION']
15
+ puts 'Must pass a VERSION=x.y.z release version'
16
+ exit
17
+ end
18
+ unless ENV['VERSION'] == VERS
19
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
20
+ exit
21
+ end
22
+ end
23
+
24
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
+ task :install_gem_no_doc => [:clean, :package] do
26
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
27
+ end
28
+
29
+ namespace :manifest do
30
+ desc 'Recreate Manifest.txt to include ALL files'
31
+ task :refresh do
32
+ `rake check_manifest | patch -p0 > Manifest.txt`
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
@@ -0,0 +1,17 @@
1
+ desc 'Generate website files'
2
+ task :website_generate => :ruby_env do
3
+ (Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
4
+ sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
5
+ end
6
+ end
7
+
8
+ desc 'Upload website files to rubyforge'
9
+ task :website_upload do
10
+ host = "#{rubyforge_username}@rubyforge.org"
11
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
12
+ local_dir = 'website'
13
+ sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
14
+ end
15
+
16
+ desc 'Generate and upload website files'
17
+ task :website => [:website_generate, :website_upload, :publish_docs]
@@ -34,4 +34,20 @@ class TestCalledByName < Test::Unit::TestCase
34
34
  end
35
35
  end
36
36
 
37
+ def test_short_circuit_implication
38
+ with(
39
+ called_by_name(:my_or) { |arg1, arg2|
40
+ if arg1
41
+ arg1
42
+ else
43
+ arg2
44
+ end
45
+ }
46
+ ) do
47
+ my_or(
48
+ true, nil.raise_missing_method_exception
49
+ )
50
+ end
51
+ end
52
+
37
53
  end
@@ -0,0 +1,239 @@
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
+ rewrite
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>rewrite</h1>
34
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/rewrite"; return false'>
35
+ <p>Get Version</p>
36
+ <a href="http://rubyforge.org/projects/rewrite" class="numbers">0.0.2</a>
37
+ </div>
38
+ <h1>&#x2192; &#8216;rewrite&#8217;</h1>
39
+
40
+
41
+ <h2>What</h2>
42
+
43
+
44
+ <p>Rewrite adds sexp-rewriting metaprogramming to Ruby. Or in plain English, Rewrite is a collection of features for Ruby programming like an implementation of <a href="http://andand.rubyforge.org">andand</a>. What makes Rewrite&#8217;s versions of these features different and possibly useful is that they are implemented by rewriting your Ruby code rather than by opening up classes like Kernel, Object, Nil, or Symbol.</p>
45
+
46
+
47
+ <h2>Installing</h2>
48
+
49
+
50
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">rewrite</span></pre></p>
51
+
52
+
53
+ <h2>The basics</h2>
54
+
55
+
56
+ <p>In your environment.rb file (Rails) or at the top of your source code file, include <code>Rewrite::With</code> and <code>Rewrite::Prelude</code>:</p>
57
+
58
+
59
+ <p><pre class='syntax'>
60
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">With</span>
61
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">Prelude</span>
62
+ </pre>This makes the <code>with</code> method available to your souce code, so you can write:</p>
63
+
64
+
65
+ <p><pre class='syntax'>
66
+ <span class="ident">with</span><span class="punct">(</span><span class="ident">andand</span><span class="punct">)</span> <span class="keyword">do</span>
67
+ <span class="punct">...</span>
68
+ <span class="ident">first_name</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">find_by_last_name</span><span class="punct">('</span><span class="string">Braithwaite</span><span class="punct">').</span><span class="ident">andand</span><span class="punct">.</span><span class="ident">first_name</span>
69
+ <span class="punct">...</span>
70
+ <span class="keyword">end</span>
71
+ </pre>The special magic here is that instead of opening up the Object and Nil classes to add <em>#andand</em>, Rewrite rewrites the ruby code inside the do/end block so that it looks roughly like this:</p>
72
+
73
+
74
+ <p><pre class='syntax'>
75
+ <span class="ident">with</span><span class="punct">(</span><span class="ident">andand</span><span class="punct">)</span> <span class="keyword">do</span>
76
+ <span class="punct">...</span>
77
+ <span class="ident">first_name</span> <span class="punct">=</span> <span class="ident">lambda</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">__1234567__</span><span class="punct">|</span>
78
+ <span class="keyword">if</span> <span class="ident">__1234567__</span><span class="punct">.</span><span class="ident">nil?</span>
79
+ <span class="constant">nil</span>
80
+ <span class="keyword">else</span>
81
+ <span class="ident">__1234567__</span><span class="punct">.</span><span class="ident">first_name</span>
82
+ <span class="keyword">end</span>
83
+ <span class="punct">}.</span><span class="ident">call</span><span class="punct">(</span><span class="constant">Person</span><span class="punct">.</span><span class="ident">find_by_last_name</span><span class="punct">('</span><span class="string">Braithwaite</span><span class="punct">'))</span>
84
+ <span class="punct">...</span>
85
+ <span class="keyword">end</span>
86
+ </pre>That&#8217;s a big win because you can use the metaprogramming features you want without worrying that you are breaking anybody else&#8217;s code. If you use an implementation of #andand that relies on opening the Object and Nil classes, how do you know you aren&#8217;t (a) breaking some other code somewhere else, or (b) exposing your code to being broken if something else changes the #andand methods?</p>
87
+
88
+
89
+ <h2>What problem does rewrite solve?</h2>
90
+
91
+
92
+ <p>Recall that when you use the “standard” implementation of things like <a href="http://andand.rubyforge.org/">andand</a> or <a href="http://ozmm.org/posts/try.html">try</a>, you are openly modifying core classes like Object.</p>
93
+
94
+
95
+ <p>Therefore, you are reaching out and touching every line of code in your project. You probably aren’t breaking everything, but even if the chance of introducing a bug by adopting something like “try” is infinitesimal for each source code file in your project, the chance grows greater and greater as your application grows.</p>
96
+
97
+
98
+ <p>The problem is that you are introducing a change on Object, and everything depends on object. This is very different than introducing a change in your code. In that case, only the other bits of code that directly depend on your code are at risk.</p>
99
+
100
+
101
+ <p>Also, imagine if you introduce try and are careful not to break anything. Now somebody else wakes up one day and decides they need a method that works like Prototype’s <a href="http://www.prototypejs.org/api/utility/try-these">Try.these</a>. They call it “try.” They just broke your code, dude! Not only are you making everything dependant upon your version of try, but your code is dependent upon everyone else not breaking try as well. It’s a train-wreck waiting to happen.</p>
102
+
103
+
104
+ <p>Rewrite restricts things like andand or try to your code and your code alone. Sure, if you introduce a bug in your code, you may break things that directly depend on your code. But if you introduce “try” using rewrite instead of modifying Object, you will not reach out across your project and break something entirely unrelated that happens to have defined its own version of try in a completely different way.</p>
105
+
106
+
107
+ <h2>How does it work?</h2>
108
+
109
+
110
+ <p>Rewrite takes your code, converts it to an sexp with Parse Tree, then rewrites the sexp using one or more rewriters you specify. Finally, it converts the sexp back to Ruby with Ruby2Ruby and evals it. It does this when the code is first read, not every time it is invoked, so we mitigate the “do not use andand in a tight loop” problem.</p>
111
+
112
+
113
+ <p>For example, rewrite converts this:</p>
114
+
115
+
116
+ <p><pre class='syntax'>
117
+ <span class="ident">emails</span><span class="punct">.</span><span class="ident">find_by_email</span><span class="punct">(</span><span class="ident">email</span><span class="punct">).</span><span class="ident">try</span><span class="punct">(</span><span class="symbol">:destroy</span><span class="punct">)</span>
118
+ </pre></p>
119
+
120
+
121
+ <p>Into:</p>
122
+
123
+
124
+ <p><pre class='syntax'>
125
+ <span class="ident">lambda</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">receiver</span><span class="punct">,</span> <span class="ident">method</span><span class="punct">|</span>
126
+ <span class="ident">receiver</span><span class="punct">.</span><span class="ident">send</span><span class="punct">(</span><span class="ident">method</span><span class="punct">)</span> <span class="keyword">if</span> <span class="ident">receiver</span><span class="punct">.</span><span class="ident">respond_to?</span> <span class="ident">method</span>
127
+ <span class="punct">}.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">emails</span><span class="punct">.</span><span class="ident">find_by_email</span><span class="punct">(</span><span class="ident">email</span><span class="punct">),</span> <span class="symbol">:destroy</span><span class="punct">)</span>
128
+ </pre></p>
129
+
130
+
131
+ <p>And this:</p>
132
+
133
+
134
+ <p><pre class='syntax'>
135
+ <span class="ident">numbers</span><span class="punct">.</span><span class="ident">andand</span><span class="punct">.</span><span class="ident">inject</span><span class="punct">(</span><span class="ident">base_sum</span><span class="punct">())</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">total</span><span class="punct">,</span> <span class="ident">number</span><span class="punct">|</span> <span class="ident">total</span> <span class="punct">+</span> <span class="ident">number</span> <span class="punct">}</span>
136
+ </pre></p>
137
+
138
+
139
+ <p>Into:</p>
140
+
141
+
142
+ <p><pre class='syntax'>
143
+ <span class="ident">lambda</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">__1234567890__</span><span class="punct">|</span>
144
+ <span class="keyword">if</span> <span class="ident">__1234567890__</span><span class="punct">.</span><span class="ident">nil?</span>
145
+ <span class="constant">nil</span>
146
+ <span class="keyword">else</span>
147
+ <span class="ident">__1234567890__</span><span class="punct">.</span><span class="ident">inject</span><span class="punct">(</span><span class="ident">base_sum</span><span class="punct">())</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">total</span><span class="punct">,</span> <span class="ident">number</span><span class="punct">|</span> <span class="ident">total</span> <span class="punct">+</span> <span class="ident">number</span> <span class="punct">}</span>
148
+ <span class="keyword">end</span>
149
+ <span class="punct">}.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">numbers</span><span class="punct">)</span>
150
+ </pre></p>
151
+
152
+
153
+ <p>Note that with the examples, the names “andand” and “try” completely go away. If someone else defines a try method elsewhere, it will not affect your code because your code never executes a method called try.</p>
154
+
155
+
156
+ <h2>How to love Rewrite without destroying Ruby</h2>
157
+
158
+
159
+ <p>If you write:</p>
160
+
161
+
162
+ <p><pre class='syntax'>
163
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">With</span>
164
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">Prelude</span>
165
+
166
+ <span class="punct">...</span>
167
+ </pre>in Kernel context (such as in Rails&#8217; <code>environment.rb</code>), you are adding methods to the global namespace. You can include Rewrite in one or more classes where you want to use its features:</p>
168
+
169
+
170
+ <p><pre class='syntax'>
171
+ <span class="keyword">class </span><span class="class">Person</span>
172
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">With</span>
173
+ <span class="ident">include</span> <span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">Prelude</span>
174
+
175
+ <span class="punct">...</span>
176
+ <span class="keyword">end</span>
177
+ </pre>Or you can go 100% safe and avoid adding anything to existing namespaces:</p>
178
+
179
+
180
+ <p><pre class='syntax'>
181
+ <span class="keyword">class </span><span class="class">Person</span>
182
+
183
+ <span class="constant">Rewrite</span><span class="punct">.</span><span class="ident">with</span><span class="punct">(</span><span class="constant">Rewrite</span><span class="punct">::</span><span class="constant">Prelude</span><span class="punct">::</span><span class="constant">Andand</span><span class="punct">.</span><span class="ident">new</span><span class="punct">)</span> <span class="keyword">do</span>
184
+ <span class="punct">...</span>
185
+ <span class="keyword">end</span>
186
+ <span class="keyword">end</span>
187
+ </pre>It&#8217;s entirely up to you.</p>
188
+
189
+
190
+ <h2>What goodies do I get?</h2>
191
+
192
+
193
+ <p>Check the <a href="http://rewrite.rubyforge.org/rdoc/">rdocs</a>, specifically the docs for <a href="http://rewrite.rubyforge.org/rdoc/classes/Rewrite/Prelude.html">Rewrite::Prelude</a>.</p>
194
+
195
+
196
+ <h2>Current Status</h2>
197
+
198
+
199
+ <p>This is just a proof-of-concept at the moment. Writing new features is torturous, so I&#8217;m not going to suggest you write your own until I figure out how to make that easy.</p>
200
+
201
+
202
+ <h2>How to submit patches</h2>
203
+
204
+
205
+ <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>
206
+
207
+
208
+ <p>The trunk repository is <code>svn://rubyforge.org/var/svn/rewrite/trunk</code> for anonymous access.</p>
209
+
210
+
211
+ <h3>Build and test instructions</h3>
212
+
213
+
214
+ <pre>cd rewrite
215
+ rake test
216
+ rake install_gem</pre>
217
+
218
+ <h2>License</h2>
219
+
220
+
221
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
222
+
223
+
224
+ <h2>Contact</h2>
225
+
226
+
227
+ <p>Comments are welcome. Send an email to <a href="mailto:raganwald+rewrite@gmail.com">Reg Braithwaite</a> email via the <a href="http://groups.google.com/group/rewrite">forum</a></p>
228
+ <p class="coda">
229
+ <a href="http://weblog.raganwald.com/">Reginald Braithwaite</a>, 18th June 2008<br>
230
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
231
+ </p>
232
+ </div>
233
+
234
+ <!-- insert site tracking codes here, like Google Urchin -->
235
+
236
+ <script type="text/javascript" src="http://pub44.bravenet.com/counter/code.php?id=404724&usernum=3754613835&cpv=2"></script>
237
+
238
+ </body>
239
+ </html>
data/website/index.txt ADDED
@@ -0,0 +1,153 @@
1
+ h1. rewrite
2
+
3
+ h1. &#x2192; 'rewrite'
4
+
5
+
6
+ h2. What
7
+
8
+ Rewrite adds sexp-rewriting metaprogramming to Ruby. Or in plain English, Rewrite is a collection of features for Ruby programming like an implementation of "andand":http://andand.rubyforge.org. What makes Rewrite's versions of these features different and possibly useful is that they are implemented by rewriting your Ruby code rather than by opening up classes like Kernel, Object, Nil, or Symbol.
9
+
10
+
11
+ h2. Installing
12
+
13
+ <pre syntax="ruby">sudo gem install rewrite</pre>
14
+
15
+ h2. The basics
16
+
17
+ In your environment.rb file (Rails) or at the top of your source code file, include @Rewrite::With@ and @Rewrite::Prelude@:
18
+
19
+ <pre syntax="ruby">
20
+ include Rewrite::With
21
+ include Rewrite::Prelude
22
+ </pre>This makes the @with@ method available to your souce code, so you can write:
23
+
24
+ <pre syntax="ruby">
25
+ with(andand) do
26
+ ...
27
+ first_name = Person.find_by_last_name('Braithwaite').andand.first_name
28
+ ...
29
+ end
30
+ </pre>The special magic here is that instead of opening up the Object and Nil classes to add _#andand_, Rewrite rewrites the ruby code inside the do/end block so that it looks roughly like this:
31
+
32
+ <pre syntax="ruby">
33
+ with(andand) do
34
+ ...
35
+ first_name = lambda { |__1234567__|
36
+ if __1234567__.nil?
37
+ nil
38
+ else
39
+ __1234567__.first_name
40
+ end
41
+ }.call(Person.find_by_last_name('Braithwaite'))
42
+ ...
43
+ end
44
+ </pre>That's a big win because you can use the metaprogramming features you want without worrying that you are breaking anybody else's code. If you use an implementation of #andand that relies on opening the Object and Nil classes, how do you know you aren't (a) breaking some other code somewhere else, or (b) exposing your code to being broken if something else changes the #andand methods?
45
+
46
+ h2. What problem does rewrite solve?
47
+
48
+ Recall that when you use the “standard” implementation of things like "andand":http://andand.rubyforge.org/ or "try":http://ozmm.org/posts/try.html, you are openly modifying core classes like Object.
49
+
50
+ Therefore, you are reaching out and touching every line of code in your project. You probably aren’t breaking everything, but even if the chance of introducing a bug by adopting something like “try” is infinitesimal for each source code file in your project, the chance grows greater and greater as your application grows.
51
+
52
+ The problem is that you are introducing a change on Object, and everything depends on object. This is very different than introducing a change in your code. In that case, only the other bits of code that directly depend on your code are at risk.
53
+
54
+ Also, imagine if you introduce try and are careful not to break anything. Now somebody else wakes up one day and decides they need a method that works like Prototype’s "Try.these":http://www.prototypejs.org/api/utility/try-these. They call it “try.” They just broke your code, dude! Not only are you making everything dependant upon your version of try, but your code is dependent upon everyone else not breaking try as well. It’s a train-wreck waiting to happen.
55
+
56
+ Rewrite restricts things like andand or try to your code and your code alone. Sure, if you introduce a bug in your code, you may break things that directly depend on your code. But if you introduce “try” using rewrite instead of modifying Object, you will not reach out across your project and break something entirely unrelated that happens to have defined its own version of try in a completely different way.
57
+
58
+ h2. How does it work?
59
+
60
+ Rewrite takes your code, converts it to an sexp with Parse Tree, then rewrites the sexp using one or more rewriters you specify. Finally, it converts the sexp back to Ruby with Ruby2Ruby and evals it. It does this when the code is first read, not every time it is invoked, so we mitigate the “do not use andand in a tight loop” problem.
61
+
62
+ For example, rewrite converts this:
63
+
64
+ <pre syntax="ruby">
65
+ emails.find_by_email(email).try(:destroy)
66
+ </pre>
67
+
68
+ Into:
69
+
70
+ <pre syntax="ruby">
71
+ lambda { |receiver, method|
72
+ receiver.send(method) if receiver.respond_to? method
73
+ }.call(emails.find_by_email(email), :destroy)
74
+ </pre>
75
+
76
+ And this:
77
+
78
+ <pre syntax="ruby">
79
+ numbers.andand.inject(base_sum()) { |total, number| total + number }
80
+ </pre>
81
+
82
+ Into:
83
+
84
+ <pre syntax="ruby">
85
+ lambda { |__1234567890__|
86
+ if __1234567890__.nil?
87
+ nil
88
+ else
89
+ __1234567890__.inject(base_sum()) { |total, number| total + number }
90
+ end
91
+ }.call(numbers)
92
+ </pre>
93
+
94
+ Note that with the examples, the names “andand” and “try” completely go away. If someone else defines a try method elsewhere, it will not affect your code because your code never executes a method called try.
95
+
96
+ h2. How to love Rewrite without destroying Ruby
97
+
98
+ If you write:
99
+
100
+ <pre syntax="ruby">
101
+ include Rewrite::With
102
+ include Rewrite::Prelude
103
+
104
+ ...
105
+ </pre>in Kernel context (such as in Rails' @environment.rb@), you are adding methods to the global namespace. You can include Rewrite in one or more classes where you want to use its features:
106
+
107
+ <pre syntax="ruby">
108
+ class Person
109
+ include Rewrite::With
110
+ include Rewrite::Prelude
111
+
112
+ ...
113
+ end
114
+ </pre>Or you can go 100% safe and avoid adding anything to existing namespaces:
115
+
116
+ <pre syntax="ruby">
117
+ class Person
118
+
119
+ Rewrite.with(Rewrite::Prelude::Andand.new) do
120
+ ...
121
+ end
122
+ end
123
+ </pre>It's entirely up to you.
124
+
125
+ h2. What goodies do I get?
126
+
127
+ Check the "rdocs":http://rewrite.rubyforge.org/rdoc/, specifically the docs for "Rewrite::Prelude":http://rewrite.rubyforge.org/rdoc/classes/Rewrite/Prelude.html.
128
+
129
+ h2. Current Status
130
+
131
+ This is just a proof-of-concept at the moment. Writing new features is torturous, so I'm not going to suggest you write your own until I figure out how to make that easy.
132
+
133
+ h2. How to submit patches
134
+
135
+ 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.
136
+
137
+ The trunk repository is <code>svn://rubyforge.org/var/svn/rewrite/trunk</code> for anonymous access.
138
+
139
+ h3. Build and test instructions
140
+
141
+ <pre>cd rewrite
142
+ rake test
143
+ rake install_gem</pre>
144
+
145
+
146
+ h2. License
147
+
148
+ This code is free to use under the terms of the MIT license.
149
+
150
+ h2. Contact
151
+
152
+ Comments are welcome. Send an email to "Reg Braithwaite":mailto:raganwald+rewrite@gmail.com email via the "forum":http://groups.google.com/group/rewrite
153
+