micon 0.1.17 → 0.1.18
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/micon.rb +8 -3
- data/lib/micon/config.rb +5 -5
- data/lib/micon/core.rb +76 -76
- data/lib/micon/helper.rb +6 -6
- data/lib/micon/metadata.rb +31 -31
- data/lib/micon/module.rb +12 -12
- data/lib/micon/spec.rb +4 -4
- data/lib/micon/support.rb +1 -1
- data/readme.md +72 -66
- data/spec/callbacks_spec.rb +18 -18
- data/spec/config_spec.rb +5 -5
- data/spec/constants_spec.rb +18 -18
- data/spec/custom_scope_spec.rb +14 -14
- data/spec/initialization_spec.rb +16 -16
- data/spec/managed_spec.rb +6 -6
- data/spec/miscellaneous_spec.rb +19 -19
- data/spec/nested_custom_scope_spec.rb +5 -5
- data/spec/spec_helper.rb +2 -2
- data/spec/static_scope_spec.rb +22 -22
- metadata +1 -12
- data/lib/micon/rad.rb +0 -8
- data/spec/example_spec.rb +0 -171
- data/spec/example_spec/lib/components/controller.rb +0 -8
- data/spec/example_spec/lib/components/logger.production.yml +0 -1
- data/spec/example_spec/lib/components/logger.rb +0 -8
- data/spec/example_spec/lib/components/logger.yml +0 -1
- data/spec/example_spec/lib/components/request.rb +0 -2
- data/spec/example_spec/lib/components/router.rb +0 -12
- data/spec/example_spec/lib/pages_controller.rb +0 -11
- data/spec/example_spec/lib/rack_adapter.rb +0 -25
- data/spec/example_spec/lib/request.rb +0 -8
data/lib/micon.rb
CHANGED
@@ -5,12 +5,17 @@ end
|
|
5
5
|
|
6
6
|
%w{
|
7
7
|
support
|
8
|
-
|
8
|
+
|
9
9
|
metadata
|
10
10
|
config
|
11
11
|
core
|
12
12
|
helper
|
13
|
-
|
13
|
+
|
14
14
|
module
|
15
15
|
class
|
16
|
-
}.each{|f| require "micon/#{f}"}
|
16
|
+
}.each{|f| require "micon/#{f}"}
|
17
|
+
|
18
|
+
# Initializing Micon
|
19
|
+
Micon::Core.send :include, Micon::Helper
|
20
|
+
micon = Micon::Core.new
|
21
|
+
micon.initialize!
|
data/lib/micon/config.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
class Micon::Config
|
1
|
+
class Micon::Config
|
2
2
|
attr_reader :micon, :name
|
3
3
|
def initialize micon, name
|
4
4
|
@micon, @name = micon, name
|
5
5
|
end
|
6
|
-
|
7
|
-
def load
|
6
|
+
|
7
|
+
def load
|
8
8
|
files = []
|
9
9
|
files.push *config_paths.collect{|path| find_file(path, $LOAD_PATH)}
|
10
10
|
files.push *runtime_config_paths.collect{|path| find_file(path, [micon.runtime_path])} if micon.runtime_path?
|
@@ -19,7 +19,7 @@ class Micon::Config
|
|
19
19
|
|
20
20
|
config.empty? ? nil : config
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
protected
|
24
24
|
def config_paths
|
25
25
|
fs_name = name.to_s.gsub(/::/, '/')
|
@@ -37,7 +37,7 @@ class Micon::Config
|
|
37
37
|
end
|
38
38
|
paths
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def find_file path, directories
|
42
42
|
files = directories.collect{|dir| "#{dir}#{path}"}.select{|f| File.exist? f}
|
43
43
|
raise "multiple configs for :#{name} component" if files.size > 1
|
data/lib/micon/core.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# Predefined scopes are: :application | :session | :instance | :"custom_name"
|
2
2
|
#
|
3
3
|
# Micons :"custom_name" are managed by 'scope_begin' / 'scope_end' methods
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# :"custom_name" can't be nested (it will destroy old and start new one) and always should be explicitly started!.
|
6
6
|
class Micon::Core
|
7
7
|
#
|
8
8
|
# Scope Management
|
9
9
|
#
|
10
10
|
attr_accessor :custom_scopes
|
11
|
-
|
11
|
+
|
12
12
|
def activate sname, container, &block
|
13
|
-
raise_without_self "Only custom scopes can be activated!" if sname == :application or sname == :instance
|
13
|
+
raise_without_self "Only custom scopes can be activated!" if sname == :application or sname == :instance
|
14
14
|
raise "container should have type of Hash but has #{container.class.name}" unless container.is_a? Hash
|
15
|
-
|
15
|
+
|
16
16
|
raise_without_self "Scope '#{sname}' already active!" if !block and @custom_scopes[sname]
|
17
|
-
|
17
|
+
|
18
18
|
if block
|
19
19
|
begin
|
20
20
|
outer_container_or_nil = @custom_scopes[sname]
|
@@ -27,7 +27,7 @@ class Micon::Core
|
|
27
27
|
@custom_scopes.delete sname
|
28
28
|
end
|
29
29
|
end
|
30
|
-
else
|
30
|
+
else
|
31
31
|
# not support nested scopes without block
|
32
32
|
@custom_scopes[sname] = container
|
33
33
|
@metadata.call_before_scope sname, container
|
@@ -36,9 +36,9 @@ class Micon::Core
|
|
36
36
|
|
37
37
|
def deactivate sname
|
38
38
|
raise_without_self "Only custom scopes can be deactivated!" if sname == :application or sname == :instance
|
39
|
-
|
39
|
+
|
40
40
|
raise_without_self "Scope '#{sname}' not active!" unless container = @custom_scopes[sname]
|
41
|
-
|
41
|
+
|
42
42
|
@metadata.call_after_scope sname, container
|
43
43
|
@custom_scopes.delete sname
|
44
44
|
container
|
@@ -49,10 +49,10 @@ class Micon::Core
|
|
49
49
|
true
|
50
50
|
else
|
51
51
|
@custom_scopes.include? sname
|
52
|
-
end
|
52
|
+
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def clear
|
55
|
+
def clear
|
56
56
|
@application.clear
|
57
57
|
@custom_scopes.clear
|
58
58
|
end
|
@@ -62,12 +62,12 @@ class Micon::Core
|
|
62
62
|
end
|
63
63
|
|
64
64
|
|
65
|
-
#
|
65
|
+
#
|
66
66
|
# Object Management
|
67
|
-
#
|
67
|
+
#
|
68
68
|
def include? key
|
69
69
|
sname = @registry[key]
|
70
|
-
|
70
|
+
|
71
71
|
case sname
|
72
72
|
when nil
|
73
73
|
false
|
@@ -84,34 +84,34 @@ class Micon::Core
|
|
84
84
|
|
85
85
|
def [] key
|
86
86
|
sname = @registry[key] || autoload_component_definition(key)
|
87
|
-
|
87
|
+
|
88
88
|
case sname
|
89
|
-
when :instance
|
89
|
+
when :instance
|
90
90
|
return create_object(key)
|
91
|
-
when :application
|
92
|
-
o = @application[key]
|
91
|
+
when :application
|
92
|
+
o = @application[key]
|
93
93
|
unless o
|
94
94
|
return create_object(key, @application)
|
95
95
|
else
|
96
96
|
return o
|
97
97
|
end
|
98
|
-
else # custom
|
98
|
+
else # custom
|
99
99
|
container = @custom_scopes[sname]
|
100
100
|
raise_without_self "Scope '#{sname}' not started!" unless container
|
101
101
|
o = container[key]
|
102
102
|
unless o
|
103
|
-
return create_object(key, container)
|
103
|
+
return create_object(key, container)
|
104
104
|
else
|
105
105
|
return o
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
def []= key, value
|
111
111
|
raise "can't assign nill as :#{key} component!" unless value
|
112
|
-
|
112
|
+
|
113
113
|
sname = @registry[key] || autoload_component_definition(key)
|
114
|
-
|
114
|
+
|
115
115
|
value = case sname
|
116
116
|
when :instance
|
117
117
|
raise_without_self "You can't outject variable with the 'instance' sname!"
|
@@ -122,15 +122,15 @@ class Micon::Core
|
|
122
122
|
raise_without_self "Scope '#{sname}' not started!" unless container
|
123
123
|
container[key] = value
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
@metadata.call_after key, value
|
127
|
-
|
127
|
+
|
128
128
|
value
|
129
|
-
end
|
129
|
+
end
|
130
130
|
|
131
131
|
def delete key
|
132
132
|
sname = @registry[key] # || autoload_component_definition(key)
|
133
|
-
|
133
|
+
|
134
134
|
case sname
|
135
135
|
when nil
|
136
136
|
when :instance
|
@@ -142,8 +142,8 @@ class Micon::Core
|
|
142
142
|
# raise_without_self "Scope '#{sname}' not started!" unless container
|
143
143
|
container.delete key if container
|
144
144
|
end
|
145
|
-
end
|
146
|
-
|
145
|
+
end
|
146
|
+
|
147
147
|
def delete_all key
|
148
148
|
metadata.delete key
|
149
149
|
delete key
|
@@ -154,23 +154,23 @@ class Micon::Core
|
|
154
154
|
self[key]
|
155
155
|
end
|
156
156
|
|
157
|
-
#
|
157
|
+
#
|
158
158
|
# Metadata
|
159
|
-
#
|
159
|
+
#
|
160
160
|
attr_accessor :metadata
|
161
|
-
|
161
|
+
|
162
162
|
def register key, options = {}, &initializer
|
163
163
|
raise "key should not be nil or false value!" unless key
|
164
|
-
options = options.symbolize_keys
|
165
|
-
|
164
|
+
options = options.symbolize_keys
|
165
|
+
|
166
166
|
sname = options.delete(:scope) || :application
|
167
167
|
dependencies = Array(options.delete(:require) || options.delete(:depends_on))
|
168
168
|
# constant = options.delete(:constant) || false
|
169
|
-
|
169
|
+
|
170
170
|
raise "unknown options :#{options.keys.join(', :')}!" unless options.empty?
|
171
|
-
|
171
|
+
|
172
172
|
unless @registry.object_id == @metadata.registry.object_id
|
173
|
-
raise "internal error, reference to registry aren't equal to actual registry!"
|
173
|
+
raise "internal error, reference to registry aren't equal to actual registry!"
|
174
174
|
end
|
175
175
|
@metadata.registry[key] = sname
|
176
176
|
@metadata.initializers[key] = [initializer, dependencies] #, constant]
|
@@ -200,11 +200,11 @@ class Micon::Core
|
|
200
200
|
else
|
201
201
|
block.call self[component]
|
202
202
|
end
|
203
|
-
end
|
203
|
+
end
|
204
204
|
@metadata.register_after component, &block
|
205
205
|
end
|
206
206
|
|
207
|
-
def before_scope sname, options = {}, &block
|
207
|
+
def before_scope sname, options = {}, &block
|
208
208
|
options[:bang] = true unless options.include? :bang
|
209
209
|
raise_without_self "scope :#{sname} already started!" if options[:bang] and active?(sname)
|
210
210
|
@metadata.register_before_scope sname, &block
|
@@ -215,9 +215,9 @@ class Micon::Core
|
|
215
215
|
raise_without_self "scope :#{sname} already started!" if options[:bang] and active?(sname)
|
216
216
|
@metadata.register_after_scope sname, &block
|
217
217
|
end
|
218
|
-
|
219
|
-
|
220
|
-
|
218
|
+
|
219
|
+
|
220
|
+
|
221
221
|
def clone
|
222
222
|
another = super
|
223
223
|
%w(@metadata @application @custom_scopes).each do |name| # @loaded_classes, @constants
|
@@ -226,45 +226,45 @@ class Micon::Core
|
|
226
226
|
end
|
227
227
|
another.instance_variable_set '@registry', another.metadata.registry
|
228
228
|
another.instance_variable_set '@initialized', another.instance_variable_get('@initialized')
|
229
|
-
another
|
229
|
+
another
|
230
230
|
end
|
231
231
|
alias_method :deep_clone, :clone
|
232
|
-
|
233
|
-
def initialize!
|
232
|
+
|
233
|
+
def initialize!
|
234
234
|
unless @initialized
|
235
235
|
# quick access to Metadata inner variable.
|
236
236
|
# I intentially broke the Metadata incapsulation to provide better performance, don't refactor it.
|
237
237
|
@registry = {} # @loaded_classes, @constants = {}, {}
|
238
238
|
@metadata = Micon::Metadata.new(@registry)
|
239
239
|
@stack = {}
|
240
|
-
|
240
|
+
|
241
241
|
@application, @custom_scopes = {}, {}
|
242
|
-
|
242
|
+
|
243
243
|
@initialized = true
|
244
244
|
end
|
245
|
-
|
246
|
-
# Micon::Core is independent itself and there can be multiple Cores simultaneously.
|
247
|
-
# But some of it's extensions can work only with one global instance, and them need to know how to get it,
|
245
|
+
|
246
|
+
# Micon::Core is independent itself and there can be multiple Cores simultaneously.
|
247
|
+
# But some of it's extensions can work only with one global instance, and them need to know how to get it,
|
248
248
|
# the MICON constant references this global instance.
|
249
249
|
Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
|
250
|
-
Object.const_set :MICON, self
|
250
|
+
Object.const_set :MICON, self
|
251
251
|
end
|
252
|
-
|
252
|
+
|
253
253
|
def deinitialize!
|
254
254
|
Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
|
255
|
-
|
255
|
+
|
256
256
|
# @loaded_classes.each do |class_name, tuple|
|
257
257
|
# namespace, const = tuple
|
258
258
|
# namespace.send(:remove_const, const)
|
259
259
|
# end
|
260
260
|
# @loaded_classes.clear
|
261
261
|
end
|
262
|
-
|
263
|
-
#
|
262
|
+
|
263
|
+
#
|
264
264
|
# :mode, :runtime_path, used in component configuration
|
265
265
|
# - 'app/runtime'
|
266
266
|
# - :development, :test, :production
|
267
|
-
#
|
267
|
+
#
|
268
268
|
def runtime_path; @runtime_path || raise(":runtime_path not defined!") end
|
269
269
|
def runtime_path= runtime_path
|
270
270
|
runtime_path, force = runtime_path
|
@@ -272,74 +272,74 @@ class Micon::Core
|
|
272
272
|
@runtime_path = runtime_path
|
273
273
|
end
|
274
274
|
def runtime_path?; !!@runtime_path end
|
275
|
-
|
275
|
+
|
276
276
|
def mode; @mode || raise(":mode not defined!") end
|
277
|
-
def mode= mode
|
278
|
-
mode, force = mode
|
277
|
+
def mode= mode
|
278
|
+
mode, force = mode
|
279
279
|
raise "some components has been already initialized before You set :mode!" unless empty? or force
|
280
280
|
@mode = mode
|
281
281
|
end
|
282
282
|
def mode?; !!@mode end
|
283
|
-
|
284
|
-
protected
|
283
|
+
|
284
|
+
protected
|
285
285
|
def autoload_component_definition key, bang = true
|
286
286
|
begin
|
287
287
|
require "components/#{key.to_s.gsub(/::/, '/')}"
|
288
288
|
rescue LoadError
|
289
|
-
end
|
289
|
+
end
|
290
290
|
sname = @registry[key]
|
291
291
|
raise_without_self "'#{key}' component not managed!" if bang and !sname
|
292
292
|
sname
|
293
293
|
end
|
294
294
|
|
295
|
-
def create_object key, container = nil
|
295
|
+
def create_object key, container = nil
|
296
296
|
initializer, dependencies, config = @metadata.initializers[key]
|
297
297
|
raise "no initializer for :#{key} component!" unless initializer
|
298
|
-
|
299
|
-
raise "component :#{key} used before it's initialization is finished!" if @stack.include? key
|
298
|
+
|
299
|
+
raise "component :#{key} used before it's initialization is finished!" if @stack.include? key
|
300
300
|
begin
|
301
301
|
dependencies.each{|d| self[d]}
|
302
|
-
@metadata.call_before key
|
302
|
+
@metadata.call_before key
|
303
303
|
|
304
304
|
# we need to check container first, in complex cases (circullar dependency)
|
305
305
|
# the object already may be initialized.
|
306
306
|
# See "should allow to use circullar dependency in :after callback".
|
307
307
|
@stack[key] = true
|
308
308
|
o = (container && container[key]) || initializer.call
|
309
|
-
|
309
|
+
|
310
310
|
unless config == false
|
311
|
-
unless config
|
311
|
+
unless config
|
312
312
|
# loading and caching config
|
313
313
|
config = get_config key
|
314
314
|
config = false unless config # we use false to differentiate from nil
|
315
315
|
@metadata.initializers[key] = [initializer, dependencies, config]
|
316
|
-
|
316
|
+
|
317
317
|
apply_config o, config if config
|
318
318
|
else
|
319
319
|
apply_config o, config
|
320
|
-
end
|
320
|
+
end
|
321
321
|
end
|
322
|
-
|
322
|
+
|
323
323
|
container[key] = o if container
|
324
|
-
|
324
|
+
|
325
325
|
raise "initializer for component :#{key} returns nill!" unless o
|
326
326
|
ensure
|
327
327
|
@stack.delete key
|
328
328
|
end
|
329
|
-
|
329
|
+
|
330
330
|
@metadata.call_after key, o
|
331
|
-
o
|
331
|
+
o
|
332
332
|
end
|
333
|
-
|
333
|
+
|
334
334
|
def get_config key
|
335
335
|
::Micon::Config.new(self, key).load
|
336
336
|
end
|
337
|
-
|
337
|
+
|
338
338
|
def apply_config component, config
|
339
339
|
# config already have keys like "#{k}="
|
340
340
|
config.each{|k, v| component.send(k, v)}
|
341
341
|
end
|
342
|
-
|
342
|
+
|
343
343
|
def name_hack namespace
|
344
344
|
if namespace
|
345
345
|
namespace.to_s.gsub("#<Class:", "").gsub(">", "")
|
data/lib/micon/helper.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
#
|
1
|
+
#
|
2
2
|
# Generates helper methods for Micon,
|
3
3
|
# so you can use micon.config instead of micon[:config]
|
4
4
|
#
|
5
|
-
module Micon::Helper
|
5
|
+
module Micon::Helper
|
6
6
|
def method_missing m, *args, &block
|
7
7
|
super if args.size > 1 or block
|
8
|
-
|
8
|
+
|
9
9
|
key = m.to_s.sub(/[?=]$/, '').to_sym
|
10
10
|
self.class.class_eval do
|
11
11
|
define_method key do
|
12
12
|
self[key]
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
define_method "#{key}=" do |value|
|
16
16
|
self[key] = value
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
define_method "#{key}?" do
|
20
20
|
include? key
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
send m, *args
|
25
25
|
end
|
26
26
|
end
|
data/lib/micon/metadata.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#
|
1
|
+
#
|
2
2
|
# This class intentially made using "wired and not clear code", to provide better performance.
|
3
|
-
#
|
3
|
+
#
|
4
4
|
class Micon::Metadata
|
5
5
|
attr_accessor :registry, :initializers, :before, :after
|
6
|
-
|
6
|
+
|
7
7
|
def initialize registry
|
8
8
|
@registry = registry
|
9
9
|
@before, @after, @before_scope, @after_scope, @initializers = {}, {}, {}, {}, {}
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def clear
|
13
13
|
@registry.clear
|
14
14
|
@initializers.clear
|
@@ -17,7 +17,7 @@ class Micon::Metadata
|
|
17
17
|
@before_scope.clear
|
18
18
|
@after_scope.clear
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def delete key
|
22
22
|
@registry.delete key
|
23
23
|
@initializers.delete key
|
@@ -26,7 +26,7 @@ class Micon::Metadata
|
|
26
26
|
@before_scope.delete key
|
27
27
|
@after_scope.delete key
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def clone
|
31
31
|
another = super
|
32
32
|
%w(@registry @before @after @before_scope @after_scope @initializers).each do |name|
|
@@ -36,43 +36,43 @@ class Micon::Metadata
|
|
36
36
|
another
|
37
37
|
end
|
38
38
|
alias_method :deep_clone, :clone
|
39
|
-
|
40
|
-
|
41
|
-
#
|
39
|
+
|
40
|
+
|
41
|
+
#
|
42
42
|
# Registry
|
43
|
-
#
|
43
|
+
#
|
44
44
|
def [] key
|
45
45
|
@registry[key]
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
# def []= key, value
|
49
49
|
# @registry[key] = value
|
50
50
|
# end
|
51
|
-
|
51
|
+
|
52
52
|
def include? key
|
53
53
|
@registry.include? key
|
54
54
|
end
|
55
|
-
|
56
|
-
|
57
|
-
#
|
55
|
+
|
56
|
+
|
57
|
+
#
|
58
58
|
# Callbacks
|
59
|
-
#
|
59
|
+
#
|
60
60
|
def register_before key, &block
|
61
61
|
raise "you should provide block!" unless block
|
62
62
|
(@before[key] ||= []) << block
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def register_after key, &block
|
66
66
|
raise "you should provide block!" unless block
|
67
67
|
(@after[key] ||= []) << block
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def call_before key
|
71
71
|
if callbacks = @before[key]
|
72
|
-
callbacks.each{|c| c.call}
|
72
|
+
callbacks.each{|c| c.call}
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
def call_after key, object
|
77
77
|
if callbacks = @after[key]
|
78
78
|
callbacks.each{|c| c.call(object)}
|
@@ -80,46 +80,46 @@ class Micon::Metadata
|
|
80
80
|
end
|
81
81
|
|
82
82
|
|
83
|
-
#
|
83
|
+
#
|
84
84
|
# Scope callbacks
|
85
|
-
#
|
85
|
+
#
|
86
86
|
def register_before_scope key, &block
|
87
87
|
raise "you should provide block!" unless block
|
88
88
|
(@before_scope[key] ||= []) << block
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def register_after_scope key, &block
|
92
92
|
raise "you should provide block!" unless block
|
93
93
|
(@after_scope[key] ||= []) << block
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
def call_before_scope key, container
|
97
97
|
if callbacks = @before_scope[key]
|
98
98
|
callbacks.each{|c| c.call container}
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
def call_after_scope key, container
|
103
103
|
if callbacks = @after_scope[key]
|
104
104
|
callbacks.each{|c| c.call container}
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
def with_scope_callbacks key, container, &block
|
109
109
|
call_before_scope key, container
|
110
110
|
result = block.call
|
111
111
|
call_after_scope key, container
|
112
112
|
result
|
113
113
|
end
|
114
|
-
|
115
|
-
|
116
|
-
#
|
114
|
+
|
115
|
+
|
116
|
+
#
|
117
117
|
# Other
|
118
|
-
#
|
118
|
+
#
|
119
119
|
# def inspect
|
120
120
|
# "Registry: " + self.registry.keys.inspect
|
121
121
|
# end
|
122
|
-
|
122
|
+
|
123
123
|
# def deep_clone
|
124
124
|
# m = Metadata.new
|
125
125
|
# m.registry = {}
|