up_the_irons-immutable 0.1 → 0.2

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.
data/README CHANGED
@@ -14,7 +14,7 @@ Child classes, however, can still override the method. So this is not like
14
14
  Java's "final" method modifier.
15
15
 
16
16
  One can argue that in OOP, if you want to reimplement or extend a method, a
17
- child class is the only place you should be doing that anyway.
17
+ child class is the only place where you should be doing that anyway.
18
18
 
19
19
  Alpha
20
20
  -----
@@ -96,7 +96,6 @@ to immutable.rb and not mess with $RUBYLIB.
96
96
  If you installed ``Immutable`` from RubyGems, put::
97
97
 
98
98
  require 'rubygems'
99
- gem 'up_the_irons-immutable'
100
99
  require 'immutable'
101
100
 
102
101
  at the top of your programs.
@@ -136,11 +135,41 @@ reimplementing them. So the following:
136
135
  end
137
136
  end
138
137
 
138
+ Will raise an error:
139
+
140
+ ::
141
+
142
+ Cannot override the immutable method: foo (Immutable::CannotOverrideMethod)
143
+
144
+ There is one option to immutable_method() called :silent. If :silent is true,
145
+ no exception will be raised. One can then do:
146
+
147
+ ::
148
+
149
+ module Foo
150
+ include Immutable
151
+
152
+ def foo
153
+ :foo
154
+ end
155
+
156
+ immutable_method :foo, :silent => true
157
+ end
158
+
159
+ module Foo
160
+ def foo
161
+ :baz
162
+ end
163
+ end
164
+
139
165
  include Foo
140
166
 
141
167
  foo # => :foo
142
168
 
143
- Returns :foo, not :baz.
169
+ foo() returns :foo, not :baz. It did not allow itself to be overriden. Using
170
+ :silent can bring a great deal of confusion to other developers wondering why
171
+ their method overrides aren't working. I would consider using :silent bad
172
+ practice in all but very limited cases. Use with extreme caution.
144
173
 
145
174
  There is an alias for immutable_method() called immutable_methods() (plural).
146
175
  Use whichever style you prefer.
@@ -148,7 +177,7 @@ Use whichever style you prefer.
148
177
  To Do
149
178
  -----
150
179
 
151
- * Add option to raise exception if code tries to modify an immutable method.
180
+ I finished my TODOs, cool.
152
181
 
153
182
  Author
154
183
  ------
@@ -177,17 +206,16 @@ Copyright
177
206
 
178
207
  Copyright (c) 2008 Garry C. Dolley
179
208
 
180
- eBay4R is free software; you can redistribute it and/or modify it under the
209
+ Immutable is free software; you can redistribute it and/or modify it under the
181
210
  terms of the GNU General Public License as published by the Free Software
182
211
  Foundation; either version 2 of the License, or (at your option) any later
183
212
  version.
184
213
 
185
- eBay4R is distributed in the hope that it will be useful, but WITHOUT ANY
214
+ Immutable is distributed in the hope that it will be useful, but WITHOUT ANY
186
215
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
187
216
  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
188
217
  details.
189
218
 
190
219
  You should have received a copy of the GNU General Public License along with
191
- eBay4R; if not, write to the Free Software Foundation, Inc., 51 Franklin
220
+ Immutable; if not, write to the Free Software Foundation, Inc., 51 Franklin
192
221
  Street, Fifth Floor, Boston, MA 02110-1301, USA
193
-
data/immutable.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = "immutable"
3
- s.version = "0.1"
3
+ s.version = "0.2"
4
4
  s.author = "Garry Dolley"
5
5
  s.email = "gdolley@ucla.edu"
6
6
  s.homepage = "http://github.com/up_the_irons/immutable/tree/master"
data/lib/immutable.rb CHANGED
@@ -1,30 +1,34 @@
1
1
  module Immutable
2
+ class CannotOverrideMethod < StandardError; end
3
+
2
4
  def self.included(mod)
3
5
  mod.extend(ClassMethods)
4
6
  end
5
7
 
6
8
  module ClassMethods
7
9
  def immutable_method(*args)
10
+ opts = args.last.is_a?(Hash) ? args.pop : {}
11
+
8
12
  args.each do |method|
9
13
  alias_method "orig_#{method}", method
10
14
  end
11
15
 
12
- @args = args
16
+ @args = args; @opts = opts
13
17
  module_eval do
14
18
  def self.method_added(sym)
15
19
  if @args
16
20
  @args.each do |method|
17
- if method
18
- if sym == method.to_sym
19
- unless called_by_method_added
20
- self.module_eval <<-"end;"
21
- def #{method.to_s}(*args, &block)
22
- orig_#{method.to_s}(*args, &block)
23
- end
24
- end;
25
- end # called_by_method_added
26
- end # method.to_sym
27
- end # method
21
+ if method && sym == method.to_sym && !called_by_method_added
22
+ unless @opts[:silent]
23
+ raise CannotOverrideMethod, "Cannot override the immutable method: #{sym}"
24
+ end
25
+
26
+ self.module_eval <<-"end;"
27
+ def #{method.to_s}(*args, &block)
28
+ orig_#{method.to_s}(*args, &block)
29
+ end
30
+ end;
31
+ end
28
32
  end # @args.each
29
33
  end # @args
30
34
  end # def self.method_added()
@@ -19,7 +19,7 @@ module Foo
19
19
  :fast
20
20
  end
21
21
 
22
- immutable_method :foo, :bar
22
+ immutable_method :foo, :bar, :silent => true
23
23
  end
24
24
 
25
25
  # Other Foo modules we can screw with, so specs don't step on each other
@@ -37,69 +37,49 @@ describe "Module Foo" do
37
37
  end
38
38
 
39
39
  describe "after redefining" do
40
- def redefine(method)
41
- Foo.module_eval <<-"end;"
42
- def #{method.to_s}
43
- :slow
44
- end
45
- end;
46
- end
47
-
48
40
  it "should not let foo() be redefined" do
49
- redefine(:foo)
41
+ redefine(Foo, :foo)
50
42
  test_it(Foo, :foo)
51
43
  end
52
44
 
53
45
  it "should not let foo() be redefined even if we try twice" do
54
- redefine(:foo)
55
- redefine(:foo)
46
+ redefine(Foo, :foo)
47
+ redefine(Foo, :foo)
56
48
  test_it(Foo, :foo)
57
49
  end
58
50
 
59
51
  it "should not let bar() be redefined" do
60
- redefine(:bar)
52
+ redefine(Foo, :bar)
61
53
  test_it(Foo, :bar)
62
54
  end
63
55
 
64
56
  it "should not let bar() be redefined even if we try twice" do
65
- redefine(:bar)
66
- redefine(:bar)
57
+ redefine(Foo, :bar)
58
+ redefine(Foo, :bar)
67
59
  test_it(Foo, :bar)
68
60
  end
69
61
  end
70
62
 
71
63
  describe "after undefining" do
72
- def undefine(method)
73
- Foo2.module_eval do
74
- undef_method(method)
75
- end
76
- end
77
-
78
64
  it "should not let foo() be undefined" do
79
- undefine(:foo)
65
+ undefine(Foo2, :foo)
80
66
  test_it(Foo2, :foo)
81
67
  end
82
68
 
83
69
  it "should not let bar() be undefined" do
84
- undefine(:bar)
70
+ undefine(Foo2, :bar)
85
71
  test_it(Foo2, :bar)
86
72
  end
87
73
  end
88
74
 
89
75
  describe "after removing" do
90
- def remove(method)
91
- Foo3.module_eval do
92
- remove_method(method)
93
- end
94
- end
95
-
96
76
  it "should not let foo() be removed" do
97
- remove(:foo)
77
+ remove(Foo3, :foo)
98
78
  test_it(Foo3, :foo)
99
79
  end
100
80
 
101
81
  it "should not let bar() be removed" do
102
- remove(:bar)
82
+ remove(Foo3, :bar)
103
83
  test_it(Foo3, :bar)
104
84
  end
105
85
  end
@@ -120,7 +100,7 @@ class Bar
120
100
  :fast
121
101
  end
122
102
 
123
- immutable_method :foo, :bar
103
+ immutable_method :foo, :bar, :silent => true
124
104
  end
125
105
 
126
106
  # Other Bar modules we can screw with, so specs don't step on each other
@@ -140,69 +120,49 @@ describe "Class Bar" do
140
120
  end
141
121
 
142
122
  describe "after redefining" do
143
- def redefine(method)
144
- Bar.module_eval <<-"end;"
145
- def #{method.to_s}
146
- :slow
147
- end
148
- end;
149
- end
150
-
151
123
  it "should not let foo() be redefined" do
152
- redefine(:foo)
124
+ redefine(Bar, :foo)
153
125
  test_it(Bar, :foo)
154
126
  end
155
127
 
156
128
  it "should not let foo() be redefined even if we try twice" do
157
- redefine(:foo)
158
- redefine(:foo)
129
+ redefine(Bar, :foo)
130
+ redefine(Bar, :foo)
159
131
  test_it(Bar, :foo)
160
132
  end
161
133
 
162
134
  it "should not let bar() be redefined" do
163
- redefine(:bar)
135
+ redefine(Bar, :bar)
164
136
  test_it(Bar, :bar)
165
137
  end
166
138
 
167
139
  it "should not let bar() be redefined even if we try twice" do
168
- redefine(:bar)
169
- redefine(:bar)
140
+ redefine(Bar, :bar)
141
+ redefine(Bar, :bar)
170
142
  test_it(Bar, :bar)
171
143
  end
172
144
  end
173
145
 
174
146
  describe "after undefining" do
175
- def undefine(method)
176
- Bar2.module_eval do
177
- undef_method(method)
178
- end
179
- end
180
-
181
147
  it "should not let foo() be undefined" do
182
- undefine(:foo)
148
+ undefine(Bar2, :foo)
183
149
  test_it(Bar2, :foo)
184
150
  end
185
151
 
186
152
  it "should not let bar() be undefined" do
187
- undefine(:bar)
153
+ undefine(Bar2, :bar)
188
154
  test_it(Bar2, :bar)
189
155
  end
190
156
  end
191
157
 
192
158
  describe "after removing" do
193
- def remove(method)
194
- Bar3.module_eval do
195
- remove_method(method)
196
- end
197
- end
198
-
199
159
  it "should not let foo() be removed" do
200
- remove(:foo)
160
+ remove(Bar3, :foo)
201
161
  test_it(Bar3, :foo)
202
162
  end
203
163
 
204
164
  it "should not let bar() be removed" do
205
- remove(:bar)
165
+ remove(Bar3, :bar)
206
166
  test_it(Bar3, :bar)
207
167
  end
208
168
  end
@@ -213,3 +173,51 @@ describe "Class Bar" do
213
173
  end
214
174
  end
215
175
  end
176
+
177
+ ##############
178
+ # Exceptions #
179
+ ##############
180
+
181
+ module Boo
182
+ include Immutable
183
+
184
+ def boo
185
+ :fast
186
+ end
187
+
188
+ immutable_method :boo
189
+ end
190
+
191
+ describe "Exceptions" do
192
+ describe "by default" do
193
+ it "should raise exception upon override" do
194
+ lambda do
195
+ redefine(Boo, :boo)
196
+ end.should raise_error(Immutable::CannotOverrideMethod, /Cannot override the immutable method: boo$/)
197
+ end
198
+ end
199
+ end
200
+
201
+ ##################
202
+ # Helper methods #
203
+ ##################
204
+
205
+ def redefine(mod, method)
206
+ mod.module_eval <<-"end;"
207
+ def #{method.to_s}
208
+ :slow
209
+ end
210
+ end;
211
+ end
212
+
213
+ def undefine(mod, method)
214
+ mod.module_eval do
215
+ undef_method(method)
216
+ end
217
+ end
218
+
219
+ def remove(mod, method)
220
+ mod.module_eval do
221
+ remove_method(method)
222
+ end
223
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: up_the_irons-immutable
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garry Dolley