micon 0.1.22 → 0.1.23
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 +1 -1
- data/lib/micon/class.rb +3 -2
- data/lib/micon/config.rb +1 -1
- data/lib/micon/core.rb +59 -83
- data/lib/micon/helper.rb +1 -4
- data/lib/micon/metadata.rb +5 -39
- data/lib/micon/module.rb +4 -49
- data/spec/config_spec.rb +10 -0
- metadata +2 -2
data/lib/micon.rb
CHANGED
data/lib/micon/class.rb
CHANGED
data/lib/micon/config.rb
CHANGED
data/lib/micon/core.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Micons :"custom_name" are managed by 'scope_begin' / 'scope_end' methods
|
4
|
-
#
|
5
|
-
# :"custom_name" can't be nested (it will destroy old and start new one) and always should be explicitly started!.
|
1
|
+
# There are 3 types of component scopes: :application, :instance and custom scope.
|
2
|
+
# Custom scopes are managed with `activate` and `deactivate` methods.
|
6
3
|
class Micon::Core
|
7
|
-
#
|
8
|
-
|
9
|
-
#
|
4
|
+
# Scope Management.
|
5
|
+
|
10
6
|
attr_accessor :custom_scopes
|
11
7
|
|
12
8
|
def activate sname, container, &block
|
@@ -61,10 +57,8 @@ class Micon::Core
|
|
61
57
|
@application.empty? and @custom_scopes.empty?
|
62
58
|
end
|
63
59
|
|
60
|
+
# Component Management.
|
64
61
|
|
65
|
-
#
|
66
|
-
# Object Management
|
67
|
-
#
|
68
62
|
def include? key
|
69
63
|
sname = @registry[key]
|
70
64
|
|
@@ -75,7 +69,7 @@ class Micon::Core
|
|
75
69
|
true
|
76
70
|
when :application
|
77
71
|
@application.include? key
|
78
|
-
else # custom
|
72
|
+
else # custom scope.
|
79
73
|
container = @custom_scopes[sname]
|
80
74
|
return false unless container
|
81
75
|
container.include? key
|
@@ -95,7 +89,7 @@ class Micon::Core
|
|
95
89
|
else
|
96
90
|
return o
|
97
91
|
end
|
98
|
-
else # custom
|
92
|
+
else # custom scope.
|
99
93
|
container = @custom_scopes[sname]
|
100
94
|
raise_without_self "Scope '#{sname}' not started!" unless container
|
101
95
|
o = container[key]
|
@@ -117,7 +111,7 @@ class Micon::Core
|
|
117
111
|
raise_without_self "You can't outject variable with the 'instance' sname!"
|
118
112
|
when :application
|
119
113
|
@application[key] = value
|
120
|
-
else # custom
|
114
|
+
else # custom scope.
|
121
115
|
container = @custom_scopes[sname]
|
122
116
|
raise_without_self "Scope '#{sname}' not started!" unless container
|
123
117
|
container[key] = value
|
@@ -129,7 +123,7 @@ class Micon::Core
|
|
129
123
|
end
|
130
124
|
|
131
125
|
def delete key
|
132
|
-
sname = @registry[key]
|
126
|
+
sname = @registry[key]
|
133
127
|
|
134
128
|
case sname
|
135
129
|
when nil
|
@@ -137,9 +131,8 @@ class Micon::Core
|
|
137
131
|
raise_without_self "You can't outject variable with the 'instance' scope!"
|
138
132
|
when :application
|
139
133
|
@application.delete key
|
140
|
-
else #
|
134
|
+
else # custom scope.
|
141
135
|
container = @custom_scopes[sname]
|
142
|
-
# raise_without_self "Scope '#{sname}' not started!" unless container
|
143
136
|
container.delete key if container
|
144
137
|
end
|
145
138
|
end
|
@@ -154,9 +147,8 @@ class Micon::Core
|
|
154
147
|
self[key]
|
155
148
|
end
|
156
149
|
|
157
|
-
#
|
158
|
-
|
159
|
-
#
|
150
|
+
# Metadata.
|
151
|
+
|
160
152
|
attr_accessor :metadata
|
161
153
|
|
162
154
|
def register key, options = {}, &initializer
|
@@ -165,7 +157,6 @@ class Micon::Core
|
|
165
157
|
|
166
158
|
sname = options.delete(:scope) || :application
|
167
159
|
dependencies = Array(options.delete(:require) || options.delete(:depends_on))
|
168
|
-
# constant = options.delete(:constant) || false
|
169
160
|
|
170
161
|
raise "unknown options :#{options.keys.join(', :')}!" unless options.empty?
|
171
162
|
|
@@ -173,17 +164,11 @@ class Micon::Core
|
|
173
164
|
raise "internal error, reference to registry aren't equal to actual registry!"
|
174
165
|
end
|
175
166
|
@metadata.registry[key] = sname
|
176
|
-
@metadata.initializers[key] = [initializer, dependencies]
|
177
|
-
# if constant
|
178
|
-
# raise "component '#{key}' defined as constant must be a symbol!" unless key.is_a? Symbol
|
179
|
-
# raise "component '#{key}' defined as constant can have only :application scope!" unless sname == :application
|
180
|
-
# @constants[key] = true
|
181
|
-
# end
|
167
|
+
@metadata.initializers[key] = [initializer, dependencies]
|
182
168
|
end
|
183
169
|
|
184
170
|
def unregister key
|
185
171
|
@metadata.delete key
|
186
|
-
# @constants.delete key
|
187
172
|
end
|
188
173
|
|
189
174
|
def before component, options = {}, &block
|
@@ -216,8 +201,6 @@ class Micon::Core
|
|
216
201
|
@metadata.register_after_scope sname, &block
|
217
202
|
end
|
218
203
|
|
219
|
-
|
220
|
-
|
221
204
|
def clone
|
222
205
|
another = super
|
223
206
|
%w(@metadata @application @custom_scopes).each do |name| # @loaded_classes, @constants
|
@@ -232,9 +215,9 @@ class Micon::Core
|
|
232
215
|
|
233
216
|
def initialize!
|
234
217
|
unless @initialized
|
235
|
-
#
|
236
|
-
#
|
237
|
-
@registry = {}
|
218
|
+
# Quick access to Metadata inner variable. I intentially broke
|
219
|
+
# the Metadata incapsulation to provide better performance, don't refactor it.
|
220
|
+
@registry = {}
|
238
221
|
@metadata = Micon::Metadata.new(@registry)
|
239
222
|
@stack = {}
|
240
223
|
|
@@ -252,19 +235,9 @@ class Micon::Core
|
|
252
235
|
|
253
236
|
def deinitialize!
|
254
237
|
Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
|
255
|
-
|
256
|
-
# @loaded_classes.each do |class_name, tuple|
|
257
|
-
# namespace, const = tuple
|
258
|
-
# namespace.send(:remove_const, const)
|
259
|
-
# end
|
260
|
-
# @loaded_classes.clear
|
261
238
|
end
|
262
239
|
|
263
|
-
#
|
264
|
-
# :mode, :runtime_path, used in component configuration
|
265
|
-
# - 'app/runtime'
|
266
|
-
# - :development, :test, :production
|
267
|
-
#
|
240
|
+
# `runtime_path` is used to search for component configurations, it may be `app/runtime` for example..
|
268
241
|
def runtime_path; @runtime_path || raise(":runtime_path not defined!") end
|
269
242
|
def runtime_path= runtime_path
|
270
243
|
runtime_path, force = runtime_path
|
@@ -273,6 +246,9 @@ class Micon::Core
|
|
273
246
|
end
|
274
247
|
def runtime_path?; !!@runtime_path end
|
275
248
|
|
249
|
+
# `mode` used to search for component configuration, examples:
|
250
|
+
# - `app/runtime/logger.production.yml`
|
251
|
+
# - `app/runtime/production/logger.yml`
|
276
252
|
def mode; @mode || raise(":mode not defined!") end
|
277
253
|
def mode= mode
|
278
254
|
mode, force = mode
|
@@ -301,23 +277,21 @@ class Micon::Core
|
|
301
277
|
dependencies.each{|d| self[d]}
|
302
278
|
@metadata.call_before key
|
303
279
|
|
304
|
-
#
|
280
|
+
# We need to check container first, in complex cases (circullar dependency)
|
305
281
|
# the object already may be initialized.
|
306
282
|
# See "should allow to use circullar dependency in :after callback".
|
307
283
|
@stack[key] = true
|
308
284
|
o = (container && container[key]) || initializer.call
|
309
285
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
apply_config o, config
|
320
|
-
end
|
286
|
+
if config
|
287
|
+
apply_config o, config
|
288
|
+
elsif config != false
|
289
|
+
# Loading and caching config.
|
290
|
+
config = get_config key
|
291
|
+
config = false unless config # We use false to differentiate from nil.
|
292
|
+
@metadata.initializers[key] = [initializer, dependencies, config]
|
293
|
+
|
294
|
+
apply_config o, config if config
|
321
295
|
end
|
322
296
|
|
323
297
|
container[key] = o if container
|
@@ -336,40 +310,42 @@ class Micon::Core
|
|
336
310
|
end
|
337
311
|
|
338
312
|
def apply_config component, config
|
339
|
-
|
340
|
-
|
313
|
+
if component.respond_to? :configure!
|
314
|
+
component.configure! config
|
315
|
+
else
|
316
|
+
config.each{|k, v| component.send("#{k}=", v)}
|
317
|
+
end
|
341
318
|
end
|
342
319
|
|
320
|
+
# Module.name doesn't works correctly for Anonymous classes,
|
321
|
+
# try to execute this code:
|
322
|
+
#
|
323
|
+
# class Module
|
324
|
+
# def const_missing const
|
325
|
+
# p self.to_s
|
326
|
+
# end
|
327
|
+
# end
|
328
|
+
#
|
329
|
+
# class A
|
330
|
+
# class << self
|
331
|
+
# def a
|
332
|
+
# p self
|
333
|
+
# MissingConst
|
334
|
+
# end
|
335
|
+
# end
|
336
|
+
# end
|
337
|
+
#
|
338
|
+
# A.a
|
339
|
+
#
|
340
|
+
# The output will be:
|
341
|
+
#
|
342
|
+
# A
|
343
|
+
# "#<Class:A>"
|
343
344
|
def name_hack namespace
|
344
345
|
if namespace
|
345
346
|
namespace.to_s.gsub("#<Class:", "").gsub(">", "")
|
346
347
|
else
|
347
348
|
""
|
348
349
|
end
|
349
|
-
# Namespace Hack description
|
350
|
-
# Module.name doesn't works correctly for Anonymous classes.
|
351
|
-
# try to execute this code:
|
352
|
-
#
|
353
|
-
#class Module
|
354
|
-
# def const_missing const
|
355
|
-
# p self.to_s
|
356
|
-
# end
|
357
|
-
#end
|
358
|
-
#
|
359
|
-
#class A
|
360
|
-
# class << self
|
361
|
-
# def a
|
362
|
-
# p self
|
363
|
-
# MissingConst
|
364
|
-
# end
|
365
|
-
# end
|
366
|
-
#end
|
367
|
-
#
|
368
|
-
#A.a
|
369
|
-
#
|
370
|
-
# the output will be:
|
371
|
-
# A
|
372
|
-
# "#<Class:A>"
|
373
|
-
#
|
374
350
|
end
|
375
351
|
end
|
data/lib/micon/helper.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
#
|
2
|
-
# Generates helper methods for Micon,
|
3
|
-
# so you can use micon.config instead of micon[:config]
|
4
|
-
#
|
1
|
+
# Generates helper methods for Micon, so you can use micon.logger instead of micon[:logger]
|
5
2
|
module Micon::Helper
|
6
3
|
def method_missing m, *args, &block
|
7
4
|
super if args.size > 1 or block
|
data/lib/micon/metadata.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
1
|
# This class intentially made using "wired and not clear code", to provide better performance.
|
3
|
-
#
|
4
2
|
class Micon::Metadata
|
5
3
|
attr_accessor :registry, :initializers, :before, :after
|
6
4
|
|
@@ -38,25 +36,13 @@ class Micon::Metadata
|
|
38
36
|
alias_method :deep_clone, :clone
|
39
37
|
|
40
38
|
|
41
|
-
#
|
42
|
-
# Registry
|
43
|
-
#
|
44
|
-
def [] key
|
45
|
-
@registry[key]
|
46
|
-
end
|
47
|
-
|
48
|
-
# def []= key, value
|
49
|
-
# @registry[key] = value
|
50
|
-
# end
|
39
|
+
# Registry.
|
51
40
|
|
52
|
-
def
|
53
|
-
|
54
|
-
end
|
41
|
+
def [] key; @registry[key] end
|
42
|
+
def include? key; @registry.include? key end
|
55
43
|
|
44
|
+
# Callbacks.
|
56
45
|
|
57
|
-
#
|
58
|
-
# Callbacks
|
59
|
-
#
|
60
46
|
def register_before key, &block
|
61
47
|
raise "you should provide block!" unless block
|
62
48
|
(@before[key] ||= []) << block
|
@@ -79,10 +65,8 @@ class Micon::Metadata
|
|
79
65
|
end
|
80
66
|
end
|
81
67
|
|
68
|
+
# Scope callbacks.
|
82
69
|
|
83
|
-
#
|
84
|
-
# Scope callbacks
|
85
|
-
#
|
86
70
|
def register_before_scope key, &block
|
87
71
|
raise "you should provide block!" unless block
|
88
72
|
(@before_scope[key] ||= []) << block
|
@@ -111,22 +95,4 @@ class Micon::Metadata
|
|
111
95
|
call_after_scope key, container
|
112
96
|
result
|
113
97
|
end
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
# Other
|
118
|
-
#
|
119
|
-
# def inspect
|
120
|
-
# "Registry: " + self.registry.keys.inspect
|
121
|
-
# end
|
122
|
-
|
123
|
-
# def deep_clone
|
124
|
-
# m = Metadata.new
|
125
|
-
# m.registry = {}
|
126
|
-
# registry.each do |k, v|
|
127
|
-
# m.registry[k] = v
|
128
|
-
# end
|
129
|
-
# p m
|
130
|
-
# m
|
131
|
-
# end
|
132
98
|
end
|
data/lib/micon/module.rb
CHANGED
@@ -1,58 +1,13 @@
|
|
1
1
|
Module.class_eval do
|
2
|
-
#
|
3
|
-
# inject attribute: :session
|
4
|
-
#
|
2
|
+
# Usage: `inject logger: :logger`.
|
5
3
|
def inject attributes
|
6
4
|
::MICON.raise_without_self "Invalid argument!" unless attributes.is_a? Hash
|
7
5
|
attributes.each do |name, specificator|
|
8
6
|
::MICON.raise_without_self "Attribute name should be a Symbol!" unless name.is_a? Symbol
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
specificator = ":#{specificator}"
|
14
|
-
else
|
15
|
-
specificator = "\"#{specificator}\""
|
16
|
-
end
|
17
|
-
|
18
|
-
script = <<-RUBY
|
19
|
-
def #{name}
|
20
|
-
::MICON[#{specificator}]
|
21
|
-
end
|
22
|
-
|
23
|
-
def #{name}= value
|
24
|
-
::MICON[#{specificator}] = value
|
25
|
-
end
|
26
|
-
|
27
|
-
def #{name}?
|
28
|
-
::MICON.include? #{specificator}
|
29
|
-
end
|
30
|
-
RUBY
|
31
|
-
|
32
|
-
self.class_eval script, __FILE__, __LINE__
|
8
|
+
define_method(name){::MICON[specificator]}
|
9
|
+
define_method("#{name}="){|value| ::MICON[specificator] = value}
|
10
|
+
define_method("#{name}?"){::MICON.include? specificator}
|
33
11
|
end
|
34
12
|
end
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
# Hook to use Constants as Components
|
39
|
-
#
|
40
|
-
# if defined? ::ClassLoader
|
41
|
-
# text = <<-TEXT
|
42
|
-
# It seems that ClassLoader already defined, but it supposed to be activated after the Micon, otherwise it can cause performance loss!
|
43
|
-
# Micon.const_missing extension should be included before than ClassLoader.const_missing otherwise the Micon.const_missing will be
|
44
|
-
# called (and will ping file system) for every loaded class!
|
45
|
-
# TEXT
|
46
|
-
# warn text
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# alias_method :const_missing_without_micon, :const_missing
|
50
|
-
# protected :const_missing_without_micon
|
51
|
-
# def const_missing const
|
52
|
-
# if value = ::MICON.get_constant(self, const)
|
53
|
-
# value
|
54
|
-
# else
|
55
|
-
# const_missing_without_micon const
|
56
|
-
# end
|
57
|
-
# end
|
58
13
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -10,6 +10,16 @@ describe "Configuration" do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
it "should allow to explicitly configure component if configure! method provided" do
|
14
|
+
logger = Object.new
|
15
|
+
logger.should_receive(:configure!).with(level: :info)
|
16
|
+
micon.register(:logger){logger}
|
17
|
+
|
18
|
+
with_load_path "#{spec_dir}/basic/lib" do
|
19
|
+
micon[:logger]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
it "should merge in order: conf <- conf.mode <- runtime <- runtime.mode" do
|
14
24
|
micon.register(:object){::OpenStruct.new}
|
15
25
|
with_load_path "#{spec_dir}/order/lib" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: micon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.23
|
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: 2011-
|
12
|
+
date: 2011-10-24 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|