-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathREADME
229 lines (152 loc) · 5.19 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
=========
Immutable
=========
:Author: Garry Dolley
:Date: 09-21-2008
:Version: v0.2
The ``Immutable`` module provides a method (immutable_method) that let's one
declare method(s) as immutable. That is, other code will not be able to
open your class and replace your method with one of the same name.
Child classes, however, can still override the method. So this is not like
Java's "final" method modifier.
One can argue that in OOP, if you want to reimplement or extend a method, a
child class is the only place where you should be doing that anyway.
Alpha
-----
This code is very new and despite a pretty comprehensive spec, I'm sure there's
cases where someone can figure out how to defeat this. So be it. :)
This code has been tested on the following systems:
* GNU/Linux (Ubuntu 8.04.1) with Ruby 1.8.6
* FreeBSD 7.0 with Ruby 1.8.6
* OpenBSD 4.3 with Ruby 1.8.6
* Mac OS X 10.5 with Ruby 1.8.6
Please see the Author section below and report any problems.
Motivation
----------
My motivation for writing something that provides what some may call "evil"
functionality of closed methods/classes came from my trials of trying to
improve Rails loading time by reimplementing some ActiveSupport methods in C
(Ruby extension). I absolutely needed my C versions of certain methods to be
present, and not clobbered by ActiveSupport.
So why didn't I just load my extension after ActiveSupport? Because by then it
is too late. Rails is already loaded, along with slow running methods that get
called over 10,000 times. Run the profiler and see for yourself:
::
./script/performance/profiler "require 'config/environment'"
Releases
--------
The latest code is in git::
* git://github.com/up_the_irons/immutable.git
Requirements
------------
* None
Optionals
---------
* RubyGems 1.2.0 or higher
Installation
------------
git
~~~
::
git clone git://github.com/up_the_irons/immutable.git
Add the path where the repo was cloned on your filesystem to $RUBYLIB, or just
use the full path when you "require". See "Getting Started" section.
RubyGems
~~~~~~~~
::
gem sources -a http://gems.github.com
sudo gem install up_the_irons-immutable
Getting Started
---------------
If you installed ``Immutable`` by cloning the git repo, put the path to the repo in
$RUBYLIB, then put::
require 'lib/immutable'
at the top of your programs. Alternatively, you can just require the full path
to immutable.rb and not mess with $RUBYLIB.
If you installed ``Immutable`` from RubyGems, put::
require 'rubygems'
require 'immutable'
at the top of your programs.
Using
-----
There's not much to say, so let me present a fully working example:
::
require 'rubygems'
require 'immutable'
module Foo
include Immutable
def foo
:foo
end
def bar
:bar
end
immutable_method :foo, :bar
end
Now methods foo() and bar() cannot be overridden by other code opening Foo and
reimplementing them. So the following:
::
module Foo
def foo
:baz
end
end
Will raise an error:
::
Cannot override the immutable method: foo (Immutable::CannotOverrideMethod)
There is one option to immutable_method() called :silent. If :silent is true,
no exception will be raised. One can then do:
::
module Foo
include Immutable
def foo
:foo
end
immutable_method :foo, :silent => true
end
module Foo
def foo
:baz
end
end
include Foo
foo # => :foo
foo() returns :foo, not :baz. It did not allow itself to be overriden. Using
:silent can bring a great deal of confusion to other developers wondering why
their method overrides aren't working. I would consider using :silent bad
practice in all but very limited cases. Use with extreme caution.
There is an alias for immutable_method() called immutable_methods() (plural).
Use whichever style you prefer.
To Do
-----
Make method_added immutable, as well as immutable_method. Write tests to try
to "defeat" an immutable method, see if we can prevent it.
I finished my TODOs, cool.
Author
------
Garry C. Dolley
gdolley [at] NOSPAM- ucla.edu
AIM: garry97531
IRC: up_the_irons in #git and #caboose on Freenode (and usually many other
channels)
Formatting
----------
This README is formatted in reStructredText [RST]_. It has the best
correlation between what a document looks like as plain text vs. its
formatted output (HTML, LaTeX, etc...). What I like best is, markup doesn't
look like markup, even though it is.
.. [RST] http://docutils.sourceforge.net/rst.html
Copyright
---------
Copyright (c) 2008,2009 Garry C. Dolley
Immutable is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
Immutable is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
Immutable; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA