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 CHANGED
@@ -15,7 +15,7 @@ end
15
15
  class
16
16
  }.each{|f| require "micon/#{f}"}
17
17
 
18
- # Initializing Micon
18
+ # Initializing Micon.
19
19
  Micon::Core.send :include, Micon::Helper
20
20
  micon = Micon::Core.new
21
21
  micon.initialize!
data/lib/micon/class.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  class Class
2
- # register_as :session, scope: :request
3
- # register_as :loggger
2
+ # Usage:
3
+ # register_as :session, scope: :request
4
+ # register_as :loggger
4
5
  def register_as *args
5
6
  ::MICON.register(*args){self.new}
6
7
  end
data/lib/micon/config.rb CHANGED
@@ -14,7 +14,7 @@ class Micon::Config
14
14
  c = YAML.load_file(f)
15
15
  next unless c
16
16
  raise "component config must be a Hash (#{f})!" unless c.is_a? Hash
17
- c.each{|k, v| config[:"#{k}="] = v}
17
+ c.each{|k, v| config[k.to_sym] = v}
18
18
  end
19
19
 
20
20
  config.empty? ? nil : config
data/lib/micon/core.rb CHANGED
@@ -1,12 +1,8 @@
1
- # Predefined scopes are: :application | :session | :instance | :"custom_name"
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
- # Scope Management
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] # || autoload_component_definition(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 # Custom
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
- # Metadata
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] #, constant]
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
- # quick access to Metadata inner variable.
236
- # I intentially broke the Metadata incapsulation to provide better performance, don't refactor it.
237
- @registry = {} # @loaded_classes, @constants = {}, {}
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
- # we need to check container first, in complex cases (circullar dependency)
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
- unless config == false
311
- unless config
312
- # loading and caching config
313
- config = get_config key
314
- config = false unless config # we use false to differentiate from nil
315
- @metadata.initializers[key] = [initializer, dependencies, config]
316
-
317
- apply_config o, config if config
318
- else
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
- # config already have keys like "#{k}="
340
- config.each{|k, v| component.send(k, v)}
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
@@ -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 include? key
53
- @registry.include? key
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
- if [Class, Module].include? specificator.class
11
- specificator = specificator.name
12
- elsif specificator.is_a? Symbol
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.22
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-09-24 00:00:00.000000000Z
12
+ date: 2011-10-24 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: