micon 0.1.22 → 0.1.23
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|