namebox 0.2.0 → 0.2.1
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/lib/namebox.rb +69 -20
- metadata +2 -2
data/lib/namebox.rb
CHANGED
@@ -13,11 +13,44 @@
|
|
13
13
|
|
14
14
|
class Namebox
|
15
15
|
|
16
|
-
#
|
16
|
+
# Currently loaded top-level modules
|
17
17
|
CORE = (Module.constants - [:Config]).
|
18
18
|
map { |c| Object.const_get(c) }.
|
19
19
|
select { |m| m.is_a? Module }.uniq
|
20
20
|
|
21
|
+
# Permits to call the previous (old) version of the method, by calling _old(...)
|
22
|
+
module Old
|
23
|
+
|
24
|
+
# Check if it's already calling old, to call old and avoid recallings.
|
25
|
+
def _calling_old? fullname
|
26
|
+
_calling_old.include? fullname
|
27
|
+
end
|
28
|
+
|
29
|
+
# Call the previous (old) version of the method.
|
30
|
+
def _old(*args, &blk)
|
31
|
+
info = Namebox.caller_to_hash(caller[0])
|
32
|
+
method_name = info[:method]
|
33
|
+
method = self.method(method_name)
|
34
|
+
owner = method.owner
|
35
|
+
fullname = "#{owner}##{method_name}"
|
36
|
+
set_calling_old fullname
|
37
|
+
r = method.call(*args, &blk)
|
38
|
+
@_calling_old.delete(fullname)
|
39
|
+
r
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# stores info whether is calling the old version
|
45
|
+
def _calling_old
|
46
|
+
@_calling_old ||= []
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_calling_old fullname
|
50
|
+
_calling_old.push fullname
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
21
54
|
class << self
|
22
55
|
|
23
56
|
# Wrapper to create a namebox only to protect modules when requiring.
|
@@ -57,12 +90,8 @@ class Namebox
|
|
57
90
|
c = cr[cr.index { |s| s.start_with? __FILE__ } - 1]
|
58
91
|
raise "Unable to find a valid caller file in #{caller.inspect}" unless c
|
59
92
|
|
60
|
-
#
|
61
|
-
|
62
|
-
raise "Unexpected caller syntax in \"#{c}\"" unless m
|
63
|
-
|
64
|
-
# label them
|
65
|
-
{:file => m[1], :line => m[2].to_i, :method => m[4]}
|
93
|
+
# convert into hash
|
94
|
+
caller_to_hash c
|
66
95
|
|
67
96
|
end
|
68
97
|
|
@@ -78,6 +107,17 @@ class Namebox
|
|
78
107
|
raise NoMethodError.new(msg)
|
79
108
|
end
|
80
109
|
|
110
|
+
def caller_to_hash a_caller
|
111
|
+
|
112
|
+
# match the info
|
113
|
+
m = a_caller.match(/^(.*?):(\d+)(:in `(.*)')?$/)
|
114
|
+
raise "Unexpected caller syntax in \"#{a_caller}\"" unless m
|
115
|
+
|
116
|
+
# label them
|
117
|
+
{:file => m[1], :line => m[2].to_i, :method => m[4]}
|
118
|
+
|
119
|
+
end
|
120
|
+
|
81
121
|
end
|
82
122
|
|
83
123
|
# +modules_to_protect+ must be the classes themselves, e.g., String, Symbol,
|
@@ -127,10 +167,10 @@ class Namebox
|
|
127
167
|
# avoid redundancy
|
128
168
|
@modules.uniq!
|
129
169
|
|
130
|
-
# include all ancestors for modules and
|
170
|
+
# include all ancestors for modules and singleton classes of classes
|
131
171
|
modules.each do |m|
|
132
172
|
@modules |= m.ancestors
|
133
|
-
@modules |=
|
173
|
+
@modules |= m.singleton_class.ancestors if m.is_a? Class
|
134
174
|
end
|
135
175
|
end
|
136
176
|
|
@@ -144,12 +184,12 @@ class Namebox
|
|
144
184
|
# select classes to protect against included modules
|
145
185
|
@classes = @modules.select { |m| m.is_a? Class }
|
146
186
|
|
147
|
-
# get
|
148
|
-
|
187
|
+
# get singleton_classes
|
188
|
+
singleton_classes = @classes.map { |c| c.singleton_class }
|
149
189
|
|
150
|
-
# include
|
151
|
-
@classes |=
|
152
|
-
@modules |=
|
190
|
+
# include singleton_classes into @classes and @modules
|
191
|
+
@classes |= singleton_classes
|
192
|
+
@modules |= singleton_classes
|
153
193
|
|
154
194
|
# save preexisting methods and included modules
|
155
195
|
inc_mods_before = get_included_modules
|
@@ -219,10 +259,10 @@ class Namebox
|
|
219
259
|
klass.send :define_method, method_name do |*args, &blk|
|
220
260
|
|
221
261
|
# check namebox visibility
|
222
|
-
if this_nb.open?
|
262
|
+
if this_nb.open? && !_calling_old?(fullname)
|
223
263
|
|
224
264
|
# namebox method; bind instance method to self.
|
225
|
-
new_method.bind(self).call(*args, &blk)
|
265
|
+
r = new_method.bind(self).call(*args, &blk)
|
226
266
|
|
227
267
|
else
|
228
268
|
|
@@ -234,7 +274,12 @@ class Namebox
|
|
234
274
|
end
|
235
275
|
|
236
276
|
end
|
277
|
+
|
237
278
|
end
|
279
|
+
|
280
|
+
# permits to call the old methods
|
281
|
+
klass.send :include, Namebox::Old
|
282
|
+
|
238
283
|
end
|
239
284
|
end
|
240
285
|
end
|
@@ -378,7 +423,7 @@ class Namebox
|
|
378
423
|
|
379
424
|
# Give a name to protector module; useful when using Method#owner.
|
380
425
|
#
|
381
|
-
|
426
|
+
protector.singleton_class.send(:define_method, :to_s) do
|
382
427
|
"Protector:#{new_module}"
|
383
428
|
end
|
384
429
|
|
@@ -389,10 +434,11 @@ class Namebox
|
|
389
434
|
protector.send :define_method, method_name do |*args, &blk|
|
390
435
|
|
391
436
|
# check namebox visibility
|
392
|
-
|
437
|
+
fullname = "#{protector}##{method_name}"
|
438
|
+
if this_nb.open? && !_calling_old?(fullname)
|
393
439
|
|
394
440
|
# namebox method; bind instance method to self.
|
395
|
-
new_method.bind(self).call(*args, &blk)
|
441
|
+
r = new_method.bind(self).call(*args, &blk)
|
396
442
|
|
397
443
|
else
|
398
444
|
|
@@ -409,7 +455,10 @@ class Namebox
|
|
409
455
|
|
410
456
|
end
|
411
457
|
|
412
|
-
#
|
458
|
+
# permits to call the old methods
|
459
|
+
new_module.send :include, Namebox::Old
|
460
|
+
|
461
|
+
# include super_tunnel in new_module (must be included after Old)
|
413
462
|
new_module.send :include, super_tunnel
|
414
463
|
|
415
464
|
@protector_modules[new_module] = protector
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: namebox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-27 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'Create namespace boxes to protect the core classes'' methods from
|
15
15
|
changes, like refinements.
|