namebox 0.0.4 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/namebox.rb +226 -208
- metadata +43 -21
data/lib/namebox.rb
CHANGED
@@ -7,6 +7,12 @@
|
|
7
7
|
#
|
8
8
|
# This software is released "AS IS", without any warranty.
|
9
9
|
# The author is not responsible for the consequences of use of this software.
|
10
|
+
#
|
11
|
+
# Version 0.1.8 - This is the last version compatible with Ruby 1.8.7.
|
12
|
+
# It's slow, memory-consuming and it has some issues about loosing 'self'
|
13
|
+
# when in class methods changed by extending modules in subclasses
|
14
|
+
# (self will be the class instead of subclass when namebox is closed).
|
15
|
+
# Next versions will be only 1.9+-compatible.
|
10
16
|
|
11
17
|
class Namebox
|
12
18
|
|
@@ -15,9 +21,12 @@ class Namebox
|
|
15
21
|
map { |c| Object.const_get(c) }.
|
16
22
|
select { |m| m.is_a? Module }.uniq
|
17
23
|
|
24
|
+
### FOR RUBY 1.8.7 USE ###
|
25
|
+
CLASS_EIGENCLASS = class << Class; self; end
|
26
|
+
|
18
27
|
class << self
|
19
28
|
|
20
|
-
#
|
29
|
+
# Wrapper to create a namebox only to protect modules when requiring.
|
21
30
|
def require resource, *modules_to_protect
|
22
31
|
|
23
32
|
new(*modules_to_protect) do
|
@@ -29,16 +38,24 @@ class Namebox
|
|
29
38
|
|
30
39
|
end
|
31
40
|
|
32
|
-
#
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
# Set the default modules to protect (file-wide, for the caller file).
|
42
|
+
# Each file you want to use #default_modules, you must define them again.
|
43
|
+
# This is to avoid conflicts when using other people libraries, which
|
44
|
+
# may want to protect different modules by default. See #default_modules
|
45
|
+
#
|
37
46
|
def default_modules= modules_to_protect
|
38
47
|
(@default_modules ||= {})[caller_info[:file]] = [modules_to_protect].flatten
|
39
48
|
end
|
40
49
|
|
41
|
-
#
|
50
|
+
# Array with default modules to protect. You may want redefine this,
|
51
|
+
# protecting Namebox itself inside another namebox, and assign it to
|
52
|
+
# a constant, which can be available thru other files in the project.
|
53
|
+
#
|
54
|
+
def default_modules
|
55
|
+
(@default_modules ||= {})[caller_info[:file]] || []
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get the caller info in a structured way (hash).
|
42
59
|
def caller_info
|
43
60
|
|
44
61
|
# search for last reference to this file in caller and take the next one
|
@@ -50,105 +67,33 @@ class Namebox
|
|
50
67
|
m = c.match(/^(.*?):(\d+)(:in `(.*)')?$/)
|
51
68
|
raise "Unexpected caller syntax in \"#{c}\"" unless m
|
52
69
|
|
53
|
-
# label
|
70
|
+
# label them
|
54
71
|
{:file => m[1], :line => m[2].to_i, :method => m[4]}
|
55
72
|
|
56
73
|
end
|
57
74
|
|
58
|
-
|
59
|
-
|
60
|
-
###################################################
|
61
|
-
|
62
|
-
# Get the super methods from klass' ancestors list.
|
63
|
-
# +is_instance+: boolean for instance or class methods
|
64
|
-
# +limit_ancestor+: the last ancestor to check for methods
|
65
|
-
# +default_method+: the method to return case not found
|
66
|
-
# +first+: returns the first method found; else returns an array
|
67
|
-
#
|
68
|
-
def super_methods(name, klass, is_instance, limit_ancestor, default_method,
|
69
|
-
first = false, &validator)
|
70
|
-
|
71
|
-
ancestors = is_instance ? klass.ancestors : class_ancestors(klass)
|
72
|
-
|
73
|
-
sm = []
|
74
|
-
limit_index = ancestors.index(limit_ancestor) || ancestors.length - 1
|
75
|
-
|
76
|
-
# skip first ancestor (0) - the class itself
|
77
|
-
#
|
78
|
-
for i in 1..limit_index
|
79
|
-
super_ancestor = ancestors[i]
|
80
|
-
begin
|
81
|
-
m = super_ancestor.instance_method(name)
|
82
|
-
rescue NameError
|
83
|
-
m = nil
|
84
|
-
end
|
85
|
-
|
86
|
-
# only owners (and the last) are interesting
|
87
|
-
next unless m && m.owner == super_ancestor || i == limit_index
|
88
|
-
|
89
|
-
# check if it matches the requisites
|
90
|
-
next unless validator.call(m)
|
91
|
-
|
92
|
-
return m if first
|
93
|
-
|
94
|
-
sm << m
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
# return found methods
|
99
|
-
return sm unless sm.empty?
|
100
|
-
|
101
|
-
# not found
|
102
|
-
first ? default_method : [default_method]
|
103
|
-
end
|
104
|
-
|
105
|
-
###################################################
|
106
|
-
# CLASS METHODS HELPERS
|
107
|
-
###################################################
|
108
|
-
|
109
|
-
# build ancestors list for class methods lookup
|
110
|
-
def class_ancestors(c)
|
75
|
+
# Raises NoMethodError, limiting the length of +obj.inspect+.
|
76
|
+
def no_method_error(obj, m_name)
|
111
77
|
|
112
|
-
#
|
113
|
-
|
78
|
+
# if inspect is too big, shorten it
|
79
|
+
obj_name = obj.inspect.to_s
|
80
|
+
obj_name = obj_name[0..45] + '...' + obj_name[-1] if obj_name.length > 50
|
114
81
|
|
115
|
-
|
116
|
-
eigenclass = class << c; self; end
|
117
|
-
mod_class = eigenclass.included_modules
|
82
|
+
msg = "Undefined method `#{m_name}' for #{obj_name}:#{obj.class}"
|
118
83
|
|
119
|
-
|
120
|
-
|
121
|
-
s = c.superclass
|
122
|
-
eigensuper = class << s; self; end
|
123
|
-
|
124
|
-
# if there's no superclass, consider Kernel as included module;
|
125
|
-
# so it won't be added now, but later, in the correct order.
|
126
|
-
mod_super = s ? eigensuper.included_modules : [Kernel]
|
127
|
-
|
128
|
-
# add eigenclass and its included modules
|
129
|
-
# (discarding the ones inherited from superclasses)
|
130
|
-
list << eigenclass
|
131
|
-
list += mod_class - mod_super
|
132
|
-
|
133
|
-
# rotate values
|
134
|
-
c, eigenclass, mod_class = s, eigensuper, mod_super
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
# finally adds Class's ancestors (including Kernel)
|
139
|
-
list += Class.ancestors
|
84
|
+
raise NoMethodError.new(msg)
|
140
85
|
end
|
141
86
|
|
142
87
|
end
|
143
88
|
|
144
89
|
# +modules_to_protect+ must be the classes themselves, e.g., String, Symbol,
|
145
|
-
# not their names ("String" or :Symbol)
|
146
|
-
# Special names are
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# Obs.:
|
151
|
-
# but
|
90
|
+
# not their names ("String" or :Symbol).<br>
|
91
|
+
# Special names are:<br>
|
92
|
+
# +:all+ => protect all known modules and submodules. It's safer but slower.<br>
|
93
|
+
# +:core+ => protect the known top-level modules.<br>
|
94
|
+
# +:default+ => protect the modules defined in +Namebox.default_modules+.<br>
|
95
|
+
# Obs.: +:core+ and +:default+ can be used together and/or with other classes,
|
96
|
+
# but +:all+ must be the only parameter if it is used.
|
152
97
|
#
|
153
98
|
def initialize *modules_to_protect, &blk
|
154
99
|
|
@@ -156,6 +101,9 @@ class Namebox
|
|
156
101
|
@enabled_files = []
|
157
102
|
@protected_methods = []
|
158
103
|
|
104
|
+
# this_nb will be useful in a closure, where self will be different
|
105
|
+
this_nb = self
|
106
|
+
|
159
107
|
# by default, get Namebox.default_modules
|
160
108
|
modules_to_protect = Namebox.default_modules if modules_to_protect.empty?
|
161
109
|
|
@@ -173,7 +121,8 @@ class Namebox
|
|
173
121
|
else
|
174
122
|
|
175
123
|
# take off the symbols
|
176
|
-
|
124
|
+
modules = modules_to_protect.select { |m| m.is_a? Module }
|
125
|
+
@modules = modules
|
177
126
|
|
178
127
|
# include default modules if wanted
|
179
128
|
@modules += Namebox.default_modules if modules_to_protect.include? :default
|
@@ -184,6 +133,11 @@ class Namebox
|
|
184
133
|
# avoid redundancy
|
185
134
|
@modules.uniq!
|
186
135
|
|
136
|
+
# include all ancestors for modules and eigenclasses of classes
|
137
|
+
modules.each do |m|
|
138
|
+
@modules |= m.ancestors
|
139
|
+
@modules |= class << m; self; end.ancestors if m.is_a? Class
|
140
|
+
end
|
187
141
|
end
|
188
142
|
|
189
143
|
# modules must be given or Namebox.default_modules must be set
|
@@ -193,7 +147,22 @@ class Namebox
|
|
193
147
|
Namebox.caller_info[:file])
|
194
148
|
end
|
195
149
|
|
196
|
-
#
|
150
|
+
# select classes to protect against included modules
|
151
|
+
@classes = @modules.select { |m| m.is_a? Class }
|
152
|
+
|
153
|
+
# hash for fast search for instances of eigenclasses
|
154
|
+
@eigen_instances = Hash[*@classes.map { |c| [class << c; self; end, c] }.flatten]
|
155
|
+
|
156
|
+
# include eigenclasses in @classes
|
157
|
+
@classes |= @eigen_instances.keys
|
158
|
+
|
159
|
+
# eigen_instances will be useful as bound local variable in a closure
|
160
|
+
# for another object; so we can't use instance var @eigen_instances
|
161
|
+
#
|
162
|
+
eigen_instances = @eigen_instances
|
163
|
+
|
164
|
+
# save preexisting methods and included modules
|
165
|
+
inc_mods_before = get_included_modules
|
197
166
|
methods_before = get_methods
|
198
167
|
|
199
168
|
# ###############################################################
|
@@ -203,155 +172,174 @@ class Namebox
|
|
203
172
|
#
|
204
173
|
# ###############################################################
|
205
174
|
|
206
|
-
# get
|
175
|
+
# get data after changes
|
176
|
+
inc_mods_after = get_included_modules
|
207
177
|
methods_after = get_methods
|
208
178
|
|
209
|
-
# compare with preexisting data to discover affected methods
|
210
|
-
unless methods_after == methods_before
|
179
|
+
# compare with preexisting data to discover affected methods and modules
|
211
180
|
|
212
|
-
|
213
|
-
|
214
|
-
methods_after.each do |fullname, info|
|
181
|
+
# compare included modules (before vs after)
|
182
|
+
unless inc_mods_after == inc_mods_before
|
215
183
|
|
216
|
-
|
217
|
-
info_old = methods_before[fullname] || {}
|
218
|
-
new_m = info[:method]
|
219
|
-
old_m = info_old[:method]
|
184
|
+
inc_mods_after.each do |klass, inc_mods|
|
220
185
|
|
221
|
-
|
222
|
-
|
186
|
+
old_modules = inc_mods_before[klass]
|
187
|
+
new_modules = inc_mods - old_modules
|
223
188
|
|
224
|
-
#
|
225
|
-
|
226
|
-
klass = info[:class]
|
227
|
-
is_instance = info[:is_instance]
|
228
|
-
old_owner = old_m && old_m.owner
|
189
|
+
# there's no new included module for this class
|
190
|
+
next if new_modules.empty?
|
229
191
|
|
230
|
-
|
231
|
-
if is_instance
|
192
|
+
new_modules.each do |new_module|
|
232
193
|
|
233
|
-
|
194
|
+
# Create a protector module to protect the changed methods.
|
195
|
+
# This protector module is specifc to new_module and klass.
|
234
196
|
#
|
235
|
-
|
197
|
+
protector = Module.new
|
198
|
+
|
199
|
+
# Create a module to enable a tunnel to bypass the new_module
|
200
|
+
# in super method lookup when namebox is closed to new_module.
|
236
201
|
#
|
237
|
-
|
202
|
+
super_tunnel = Module.new
|
238
203
|
|
239
|
-
#
|
240
|
-
|
241
|
-
|
242
|
-
|
204
|
+
# Give name to protector module; useful when using Method#owner.
|
205
|
+
#
|
206
|
+
class << protector; self; end.send(:define_method, :to_s) do
|
207
|
+
"Protector:#{new_module}/#{klass}"
|
243
208
|
end
|
244
209
|
|
245
|
-
|
246
|
-
klass.send :define_method, name do |*args, &blk|
|
210
|
+
new_module.instance_methods.each do |method_name|
|
247
211
|
|
248
|
-
|
249
|
-
if this_nb.open?
|
212
|
+
new_method = new_module.instance_method(method_name)
|
250
213
|
|
251
|
-
|
252
|
-
|
253
|
-
|
214
|
+
protector.send :define_method, method_name do |*args, &blk|
|
215
|
+
if this_nb.open?
|
216
|
+
new_method.bind(self).call(*args, &blk)
|
217
|
+
else
|
218
|
+
begin
|
219
|
+
super_tunnel.instance_method(method_name).bind(self).call(*args, &blk)
|
220
|
+
rescue NoMethodError
|
254
221
|
|
255
|
-
|
222
|
+
# Can throw error in two cases:
|
223
|
+
# 1. There's really no super method (Ruby >= 1.9)
|
224
|
+
# 2. 1.8.7 does not find super when in a module after binding.
|
225
|
+
#
|
226
|
+
raise if RUBY_VERSION >= '1.9.0'
|
256
227
|
|
257
|
-
|
258
|
-
|
259
|
-
# (someone can attach a new definition to some ancestor)
|
228
|
+
# future method
|
229
|
+
m = nil
|
260
230
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
231
|
+
# search the method in old modules
|
232
|
+
old_modules.each do |old_module|
|
233
|
+
begin
|
234
|
+
m = old_module.instance_method(method_name).bind(self)
|
235
|
+
break
|
236
|
+
rescue NameError
|
237
|
+
# try next
|
238
|
+
end
|
239
|
+
end
|
265
240
|
|
266
|
-
|
241
|
+
unless m
|
267
242
|
|
268
|
-
|
243
|
+
# last try: superklass
|
244
|
+
begin
|
245
|
+
superklass = klass.superclass
|
269
246
|
|
270
|
-
|
271
|
-
|
272
|
-
obj = obj[0..45] + '...' + obj[-1] if obj.length > 50
|
247
|
+
# superklass exist?
|
248
|
+
raise NameError unless superklass
|
273
249
|
|
274
|
-
|
275
|
-
|
276
|
-
end
|
250
|
+
# Ruby 1.8.7 get wrong superclass for eigenclasses
|
251
|
+
if superklass == CLASS_EIGENCLASS
|
277
252
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
253
|
+
# Get a bound method for superclass (although self
|
254
|
+
# won't be the same: superclass instead of klass).
|
255
|
+
# Can raise NameError if method does not exist.
|
256
|
+
#
|
257
|
+
m = eigen_instances[klass].superclass.method(method_name)
|
282
258
|
|
283
|
-
|
259
|
+
else
|
284
260
|
|
285
|
-
|
286
|
-
|
287
|
-
# PROTECT CLASS METHODS
|
288
|
-
#
|
289
|
-
##########################################################
|
261
|
+
# Try to get method; raises NameError if it doesn't exist.
|
262
|
+
m = superklass.instance_method(method_name).bind(self)
|
290
263
|
|
291
|
-
|
292
|
-
new_methods = Namebox.super_methods(name, klass, is_instance,
|
293
|
-
old_owner, new_m) do |sm|
|
294
|
-
sm != old_m
|
295
|
-
end
|
264
|
+
end
|
296
265
|
|
297
|
-
|
298
|
-
|
266
|
+
rescue NameError
|
267
|
+
Namebox.no_method_error(self, method_name)
|
268
|
+
end
|
269
|
+
end
|
299
270
|
|
300
|
-
|
301
|
-
|
271
|
+
m.call(*args, &blk)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
302
275
|
|
303
|
-
|
304
|
-
|
305
|
-
|
276
|
+
super_tunnel.send :define_method, method_name do |*args, &blk|
|
277
|
+
super(*args, &blk)
|
278
|
+
end
|
306
279
|
|
307
|
-
|
280
|
+
end
|
308
281
|
|
309
|
-
|
310
|
-
|
311
|
-
# (someone can attach a new definition to some ancestor)
|
282
|
+
# include super_tunnel in new_module
|
283
|
+
new_module.send :include, super_tunnel
|
312
284
|
|
313
|
-
|
314
|
-
|
315
|
-
!new_methods.include?(sm)
|
316
|
-
end
|
285
|
+
# reincludes the new_module with super_tunnel to allow bind(self)
|
286
|
+
klass.send :include, new_module
|
317
287
|
|
318
|
-
|
288
|
+
# finally, include the protector in the class
|
289
|
+
klass.send :include, protector
|
319
290
|
|
320
|
-
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
321
294
|
|
322
|
-
|
323
|
-
|
324
|
-
obj = obj[0..45] + '...' + obj[-1] if obj.length > 50
|
295
|
+
# Compare changed methods (before vs after)
|
296
|
+
unless methods_after == methods_before
|
325
297
|
|
326
|
-
|
327
|
-
"for #{obj}:#{self.class}")
|
328
|
-
end
|
298
|
+
methods_after.each do |fullname, info|
|
329
299
|
|
330
|
-
|
300
|
+
# get old method
|
301
|
+
info_old = methods_before[fullname] || {}
|
302
|
+
new_m = info[:method]
|
303
|
+
old_m = info_old[:method]
|
331
304
|
|
332
|
-
|
333
|
-
|
305
|
+
# don't touch unmodified methods
|
306
|
+
next if new_m == old_m
|
334
307
|
|
335
|
-
|
308
|
+
# method was modified! take some info
|
309
|
+
m_name = info[:name]
|
310
|
+
klass = info[:class]
|
311
|
+
new_bound_m = info[:bound]
|
312
|
+
old_bound_m = info_old[:bound]
|
336
313
|
|
337
|
-
|
338
|
-
|
339
|
-
m = ObjectSpace.each_object(m.owner).to_a.last.method(name)
|
314
|
+
# redefine the method, which will check namebox visibility dinamically
|
315
|
+
klass.send :define_method, m_name do |*args, &blk|
|
340
316
|
|
341
|
-
|
317
|
+
# check namebox visibility
|
318
|
+
if this_nb.open?
|
342
319
|
|
343
|
-
|
344
|
-
|
320
|
+
# Call the new method. Instance methods are unbound; bind to self.
|
321
|
+
m = (new_bound_m || new_m.bind(self)).call(*args, &blk)
|
322
|
+
|
323
|
+
else
|
324
|
+
|
325
|
+
# old method or super
|
326
|
+
if old_m
|
327
|
+
(old_bound_m || old_m.bind(self)).call(*args, &blk)
|
328
|
+
else
|
329
|
+
begin
|
330
|
+
super(*args, &blk)
|
331
|
+
rescue NoMethodError
|
332
|
+
Namebox.no_method_error(self, m_name)
|
333
|
+
end
|
345
334
|
end
|
346
|
-
end
|
347
335
|
|
336
|
+
end
|
348
337
|
end
|
349
338
|
end
|
350
339
|
end
|
351
340
|
end
|
352
341
|
|
353
|
-
|
354
|
-
# open a namebox region for visibility in the caller file at caller line
|
342
|
+
# Open a namebox region for visibility in the caller file at caller line.
|
355
343
|
def open
|
356
344
|
info = ranges_info
|
357
345
|
|
@@ -365,7 +353,7 @@ class Namebox
|
|
365
353
|
end
|
366
354
|
|
367
355
|
|
368
|
-
#
|
356
|
+
# Close the namebox visible region in the caller file.
|
369
357
|
def close
|
370
358
|
info = ranges_info
|
371
359
|
|
@@ -388,7 +376,7 @@ class Namebox
|
|
388
376
|
info[:ranges] << r unless info[:ranges].include? r
|
389
377
|
end
|
390
378
|
|
391
|
-
#
|
379
|
+
# Check namebox visibility (openness).
|
392
380
|
def open?
|
393
381
|
|
394
382
|
# check file before checking ranges
|
@@ -414,15 +402,14 @@ class Namebox
|
|
414
402
|
false
|
415
403
|
end
|
416
404
|
|
417
|
-
|
418
|
-
# open namebox in entire caller file (valid only after called!)
|
405
|
+
# Open namebox in entire caller file (valid only after called!).
|
419
406
|
def file_wide
|
420
407
|
@enabled_files << Namebox.caller_info[:file]
|
421
408
|
end
|
422
409
|
|
423
410
|
private
|
424
411
|
|
425
|
-
# Get line ranges info for the caller file
|
412
|
+
# Get line ranges info for the caller file.
|
426
413
|
def ranges_info ci = Namebox.caller_info
|
427
414
|
|
428
415
|
ranges = enabled_ranges[ci[:file]] ||= []
|
@@ -435,30 +422,61 @@ class Namebox
|
|
435
422
|
ci
|
436
423
|
end
|
437
424
|
|
438
|
-
# Stores enabled line ranges of caller files for this module
|
425
|
+
# Stores enabled line ranges of caller files for this module.
|
439
426
|
def enabled_ranges
|
440
427
|
@enabled_ranges ||= {}
|
441
428
|
end
|
442
429
|
|
443
|
-
#
|
430
|
+
# Get methods in use on modules to protect.
|
444
431
|
def get_methods
|
445
432
|
gm = {}
|
446
433
|
|
447
434
|
@modules.each do |c|
|
448
435
|
|
449
|
-
|
436
|
+
# get eigenclass
|
437
|
+
ec = class << c; self; end
|
438
|
+
|
439
|
+
c.instance_methods(false).each do |m|
|
450
440
|
fullname = "#{c}##{m}"
|
451
|
-
gm[fullname] = {:class => c, :
|
452
|
-
:method => c.instance_method(m) }
|
441
|
+
gm[fullname] = {:class => c, :name => m, :method => c.instance_method(m) }
|
453
442
|
end
|
454
443
|
|
455
|
-
c.methods.each do |m|
|
444
|
+
c.methods(false).each do |m|
|
456
445
|
fullname = "#{c}.#{m}"
|
457
|
-
gm[fullname] = {:class =>
|
446
|
+
gm[fullname] = {:class => ec, :name => m, :method => ec.instance_method(m),
|
447
|
+
:bound => c.method(m) }
|
458
448
|
end
|
459
449
|
|
460
450
|
end
|
461
451
|
|
462
452
|
gm
|
463
453
|
end
|
454
|
+
|
455
|
+
# Get modules included by the classes being protected.
|
456
|
+
def get_included_modules
|
457
|
+
inc_mods = {}
|
458
|
+
|
459
|
+
@classes.each do |c|
|
460
|
+
super_c = get_superclass(c)
|
461
|
+
|
462
|
+
# superclass included modules must be [] even when superclass is nil
|
463
|
+
super_inc_mods = super_c && super_c.included_modules || []
|
464
|
+
|
465
|
+
# get modules included by the class only, not by superclasses.
|
466
|
+
inc_mods[c] = c.included_modules - super_inc_mods
|
467
|
+
end
|
468
|
+
|
469
|
+
inc_mods
|
470
|
+
end
|
471
|
+
|
472
|
+
# Get superclass of a class; correct values for eigenclasses in 1.8.7.
|
473
|
+
def get_superclass(c)
|
474
|
+
s = c.superclass
|
475
|
+
if s == CLASS_EIGENCLASS
|
476
|
+
# Ruby 1.8.7 limitation
|
477
|
+
s = class << @eigen_instances[c].superclass; self; end
|
478
|
+
end
|
479
|
+
s
|
480
|
+
end
|
481
|
+
|
464
482
|
end
|
metadata
CHANGED
@@ -1,48 +1,70 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: namebox
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 8
|
10
|
+
version: 0.1.8
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Sony Santos
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
17
|
+
|
18
|
+
date: 2013-01-20 00:00:00 Z
|
13
19
|
dependencies: []
|
14
|
-
|
15
|
-
|
20
|
+
|
21
|
+
description: |-
|
22
|
+
Create namespace boxes to protect the core classes' methods from changes, like refinements.
|
23
|
+
|
24
|
+
Note: this is the last version compatible with Ruby 1.8.7. It's slow, memory-consuming and it has some issues about loosing 'self' when in class methods changed by extending modules in subclasses (self will be the class instead of subclass when namebox is closed). Next versions will be only 1.9+-compatible.
|
16
25
|
email: sony.fermino@gmail.com
|
17
26
|
executables: []
|
27
|
+
|
18
28
|
extensions: []
|
29
|
+
|
19
30
|
extra_rdoc_files: []
|
20
|
-
|
31
|
+
|
32
|
+
files:
|
21
33
|
- lib/namebox.rb
|
22
34
|
homepage: http://rubychallenger.blogspot.com.br/2013/01/namebox.html
|
23
|
-
licenses:
|
35
|
+
licenses:
|
24
36
|
- Public Domain
|
25
37
|
post_install_message:
|
26
38
|
rdoc_options: []
|
27
|
-
|
39
|
+
|
40
|
+
require_paths:
|
28
41
|
- lib
|
29
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
43
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 57
|
48
|
+
segments:
|
49
|
+
- 1
|
50
|
+
- 8
|
51
|
+
- 7
|
34
52
|
version: 1.8.7
|
35
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
54
|
none: false
|
37
|
-
requirements:
|
38
|
-
- -
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
41
62
|
requirements: []
|
63
|
+
|
42
64
|
rubyforge_project:
|
43
65
|
rubygems_version: 1.8.24
|
44
66
|
signing_key:
|
45
67
|
specification_version: 3
|
46
|
-
summary: Create namespace boxes to protect the core classes' methods from changes,
|
47
|
-
like refinements
|
68
|
+
summary: Create namespace boxes to protect the core classes' methods from changes, like refinements.
|
48
69
|
test_files: []
|
70
|
+
|