Class: Micon::Core

Inherits:
Object
  • Object
show all
Defined in:
lib/micon/core.rb

Overview

There are 3 types of component scopes: :application, :instance and custom scope. Custom scopes are managed with activate and deactivate methods.

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object (protected)

Generates helper methods, so you can use micon.logger instead of micon[:logger]



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/micon/core.rb', line 373

def method_missing m, *args, &block
  super if args.size > 1 or block

  key = m.to_s.sub(/[?=]$/, '').to_sym
  self.class.class_eval do
    define_method key do
      self[key]
    end

    define_method "#{key}=" do |value|
      self[key] = value
    end

    define_method "#{key}?" do
      include? key
    end
  end

  send m, *args
end

Instance Attribute Details

#custom_scopesObject

Scope Management.



6
7
8
# File 'lib/micon/core.rb', line 6

def custom_scopes
  @custom_scopes
end

#metadataObject

Metadata.



152
153
154
# File 'lib/micon/core.rb', line 152

def 
  
end

Instance Method Details

#[](key) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/micon/core.rb', line 79

def [] key
  sname = @registry[key] || autoload_component_definition(key)

  case sname
  when :instance
    return create_object(key)
  when :application
    o = @application[key]
    unless o
      return create_object(key, @application)
    else
      return o
    end
  else # custom scope.
    container = @custom_scopes[sname]
    raise_without_self "Scope '#{sname}' not started!" unless container
    o = container[key]
    unless o
      return create_object(key, container)
    else
      return o
    end
  end
end

#[]=(key, value) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/micon/core.rb', line 104

def []= key, value
  raise "can't assign nill as :#{key} component!" unless value

  sname = @registry[key] || autoload_component_definition(key)

  value = case sname
  when :instance
    raise_without_self "You can't outject variable with the 'instance' sname!"
  when :application
    @application[key] = value
  else # custom scope.
    container = @custom_scopes[sname]
    raise_without_self "Scope '#{sname}' not started!" unless container
    container[key] = value
  end

  .call_after key, value

  value
end

#activate(sname, container = {}, &block) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/micon/core.rb', line 8

def activate sname, container = {}, &block
  raise_without_self "Only custom scopes can be activated!" if sname == :application or sname == :instance
  raise "container should have type of Hash but has #{container.class.name}" unless container.is_a? Hash

  raise_without_self "Scope '#{sname}' already active!" if !block and @custom_scopes[sname]

  if block
    begin
      outer_container_or_nil = @custom_scopes[sname]
      @custom_scopes[sname] = container
      .with_scope_callbacks sname, container, &block
    ensure
      if outer_container_or_nil
        @custom_scopes[sname] = outer_container_or_nil
      else
        @custom_scopes.delete sname
      end
    end
  else
    # not support nested scopes without block
    @custom_scopes[sname] = container
    .call_before_scope sname, container
  end
end

#active?(sname) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
48
49
# File 'lib/micon/core.rb', line 43

def active? sname
  if sname == :application or sname == :instance
    true
  else
    @custom_scopes.include? sname
  end
end

#after(component, options = {}, &block) ⇒ Object



178
179
180
181
182
183
184
185
186
187
# File 'lib/micon/core.rb', line 178

def after component, options = {}, &block
  if include? component
    if options[:bang]
      raise_without_self "component :#{component} already created!"
    else
      block.call self[component]
    end
  end
  .register_after component, &block
end

#after_scope(sname, options = {}, &block) ⇒ Object



195
196
197
198
199
# File 'lib/micon/core.rb', line 195

def after_scope sname, options = {}, &block
  options[:bang] = true unless options.include? :bang
  raise_without_self "scope :#{sname} already started!" if options[:bang] and active?(sname)
  .register_after_scope sname, &block
end

#before(component, options = {}, &block) ⇒ Object



173
174
175
176
# File 'lib/micon/core.rb', line 173

def before component, options = {}, &block
  raise_without_self "component :#{component} already created!" if options[:bang] and include?(component)
  .register_before component, &block
end

#before_scope(sname, options = {}, &block) ⇒ Object



189
190
191
192
193
# File 'lib/micon/core.rb', line 189

def before_scope sname, options = {}, &block
  options[:bang] = true unless options.include? :bang
  raise_without_self "scope :#{sname} already started!" if options[:bang] and active?(sname)
  .register_before_scope sname, &block
end

#clearObject



51
52
53
54
# File 'lib/micon/core.rb', line 51

def clear
  @application.clear
  @custom_scopes.clear
end

#cloneObject Also known as: deep_clone



201
202
203
204
205
206
207
208
209
210
# File 'lib/micon/core.rb', line 201

def clone
  another = super
  %w(@metadata @application @custom_scopes).each do |name| # @loaded_classes, @constants
    value = instance_variable_get name
    another.instance_variable_set name, value.clone
  end
  another.instance_variable_set '@registry', another..registry
  another.instance_variable_set '@initialized', another.instance_variable_get('@initialized')
  another
end

#deactivate(sname) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/micon/core.rb', line 33

def deactivate sname
  raise_without_self "Only custom scopes can be deactivated!" if sname == :application or sname == :instance

  raise_without_self "Scope '#{sname}' not active!" unless container = @custom_scopes[sname]

  .call_after_scope sname, container
  @custom_scopes.delete sname
  container
end

#deinitialize!Object



233
234
235
# File 'lib/micon/core.rb', line 233

def deinitialize!
  Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
end

#delete(key) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/micon/core.rb', line 125

def delete key
  sname = @registry[key]

  case sname
  when nil
  when :instance
    raise_without_self "You can't outject variable with the 'instance' scope!"
  when :application
    @application.delete key
  else # custom scope.
    container = @custom_scopes[sname]
    container.delete key if container
  end
end

#delete_all(key) ⇒ Object



140
141
142
143
# File 'lib/micon/core.rb', line 140

def delete_all key
  .delete key
  delete key
end

#development(&block) ⇒ Object



261
# File 'lib/micon/core.rb', line 261

def development █ block.call if development? end

#development?Boolean

Returns:

  • (Boolean)


257
# File 'lib/micon/core.rb', line 257

def development?; mode == :development end

#empty?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/micon/core.rb', line 56

def empty?
  @application.empty? and @custom_scopes.empty?
end

#include?(key) ⇒ Boolean

Component Management.

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/micon/core.rb', line 62

def include? key
  sname = @registry[key]

  case sname
  when nil
    false
  when :instance
    true
  when :application
    @application.include? key
  else # custom scope.
    container = @custom_scopes[sname]
    return false unless container
    container.include? key
  end
end

#initialize!Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/micon/core.rb', line 213

def initialize!
  unless @initialized
    # Quick access to Metadata inner variable. I intentially broke
    # the Metadata incapsulation to provide better performance, don't refactor it.
    @registry = {}
     = Micon::.new(@registry)
    @stack = {}

    @application, @custom_scopes = {}, {}

    @initialized = true
  end

  # Micon::Core is independent itself and there can be multiple Cores simultaneously.
  # But some of its extensions can work only with one global instance, and them need to know how to get it,
  # the MICON constant references this global instance.
  Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
  Object.const_set :MICON, self
end

#modeObject

mode used to search for component configuration, examples:

  • app/runtime/logger.production.yml

  • app/runtime/production/logger.yml



249
# File 'lib/micon/core.rb', line 249

def mode; @mode ||= :development end

#mode=(mode) ⇒ Object



250
251
252
253
254
# File 'lib/micon/core.rb', line 250

def mode= mode
  mode, force = mode
  raise "some components have been already initialized before You set :mode!" unless empty? or force
  @mode = mode
end

#mode?Boolean

Returns:

  • (Boolean)


255
# File 'lib/micon/core.rb', line 255

def mode?; !!@mode end

#production(&block) ⇒ Object



262
# File 'lib/micon/core.rb', line 262

def production █ block.call if production? end

#production?Boolean

Returns:

  • (Boolean)


258
# File 'lib/micon/core.rb', line 258

def production?; mode == :production end

#raise_without_self(message) ⇒ Object

Raises:

  • (RuntimeError)


265
266
267
# File 'lib/micon/core.rb', line 265

def raise_without_self message
  raise RuntimeError, message, caller.select{|path| path !~ /\/lib\/micon\//}
end

#register(key, options = {}, &initializer) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/micon/core.rb', line 154

def register key, options = {}, &initializer
  raise "key should not be nil or false value!" unless key

  sname = options.delete(:scope) || :application
  dependencies = Array(options.delete(:require) || options.delete(:depends_on))

  raise "unknown options :#{options.keys.join(', :')}!" unless options.empty?

  unless @registry.object_id == .registry.object_id
    raise "internal error, reference to registry aren't equal to actual registry!"
  end
  .registry[key] = sname
  .initializers[key] = [initializer, dependencies]
end

#reset(key) ⇒ Object



145
146
147
148
# File 'lib/micon/core.rb', line 145

def reset key
  delete key
  self[key]
end

#runtime_pathObject

runtime_path is used to search for component configurations, it may be app/runtime for example..



238
# File 'lib/micon/core.rb', line 238

def runtime_path; @runtime_path ||= File.expand_path('.') end

#runtime_path=(runtime_path) ⇒ Object



239
240
241
242
243
# File 'lib/micon/core.rb', line 239

def runtime_path= runtime_path
  runtime_path, force = runtime_path
  raise "some components have been already initialized before You set :runtime_path!" unless empty? or force
  @runtime_path = runtime_path
end

#runtime_path?Boolean

Returns:

  • (Boolean)


244
# File 'lib/micon/core.rb', line 244

def runtime_path?; !!@runtime_path end

#test(&block) ⇒ Object



263
# File 'lib/micon/core.rb', line 263

def test █ block.call if test? end

#test?Boolean

Returns:

  • (Boolean)


259
# File 'lib/micon/core.rb', line 259

def test?; mode == :test end

#unregister(key) ⇒ Object



169
170
171
# File 'lib/micon/core.rb', line 169

def unregister key
  .delete key
end