Class: Micon::Core

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/micon/core.rb,
lib/micon/support.rb

Overview

Predefined scopes are: :application | :session | :instance | :“custom_name”

Micons :“custom_name” are managed by ‘scope_begin’ / ‘scope_end’ methods

:“custom_name” can’t be nested (it will destroy old and start new one) and always should be explicitly started!.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#method_missing

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Micon::Helper

Instance Attribute Details

#custom_scopesObject

Scope Management



10
11
12
# File 'lib/micon/core.rb', line 10

def custom_scopes
  @custom_scopes
end

#metadataObject

Metadata



160
161
162
# File 'lib/micon/core.rb', line 160

def 
  @metadata
end

Instance Method Details

#[](key) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/micon/core.rb', line 85

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        
    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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/micon/core.rb', line 110

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
    container = @custom_scopes[sname]
    raise_without_self "Scope '#{sname}' not started!" unless container
    container[key] = value
  end
  
  @metadata.call_after key, value
  
  value
end

#activate(sname, container, &block) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/micon/core.rb', line 12

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
      @metadata.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
    @metadata.call_before_scope sname, container
  end
end

#active?(sname) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
# File 'lib/micon/core.rb', line 47

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

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



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/micon/core.rb', line 195

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

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



213
214
215
216
217
# File 'lib/micon/core.rb', line 213

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)
  @metadata.register_after_scope sname, &block
end

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



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

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

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



207
208
209
210
211
# File 'lib/micon/core.rb', line 207

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)
  @metadata.register_before_scope sname, &block
end

#clearObject



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

def clear      
  @application.clear
  @custom_scopes.clear
end

#cloneObject Also known as: deep_clone



221
222
223
224
225
226
227
228
229
230
# File 'lib/micon/core.rb', line 221

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



37
38
39
40
41
42
43
44
45
# File 'lib/micon/core.rb', line 37

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]

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

#deinitialize!Object



253
254
255
256
257
258
259
260
261
# File 'lib/micon/core.rb', line 253

def deinitialize!
  Object.send(:remove_const, :MICON) if Object.const_defined?(:MICON)
  
  # @loaded_classes.each do |class_name, tuple|
  #   namespace, const = tuple
  #   namespace.send(:remove_const, const)
  # end
  # @loaded_classes.clear
end

#delete(key) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/micon/core.rb', line 131

def delete key
  sname = @registry[key] # || autoload_component_definition(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
    container = @custom_scopes[sname]
    # raise_without_self "Scope '#{sname}' not started!" unless container
    container.delete key if container
  end
end

#delete_all(key) ⇒ Object



147
148
149
150
# File 'lib/micon/core.rb', line 147

def delete_all key
  .delete key
  delete key
end

#empty?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/micon/core.rb', line 60

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

#include?(key) ⇒ Boolean

Object Management

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/micon/core.rb', line 68

def include? key
  sname = @registry[key]

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

#initialize!Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/micon/core.rb', line 233

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 = {} # @loaded_classes, @constants = {}, {}
    @metadata = Micon::Metadata.new(@registry)
    @stack = {}
  
    @application, @custom_scopes = {}, {}
    
    @initialized = true
  end
  
  # Micon::Core is independent itself and there can be multiple Cores simultaneously. 
  # But some of it's 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



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

def mode; @mode || raise(":mode not defined!") end

#mode=(mode) ⇒ Object



277
278
279
280
281
# File 'lib/micon/core.rb', line 277

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

#mode?Boolean

Returns:

  • (Boolean)


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

def mode?; !!@mode end

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



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/micon/core.rb', line 162

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

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

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

  unless @registry.object_id == @metadata.registry.object_id
    raise "internal error, reference to registry aren't equal to actual registry!" 
  end
  @metadata.registry[key] = sname
  @metadata.initializers[key] = [initializer, dependencies] #, constant]
  # if constant
  #   raise "component '#{key}' defined as constant must be a symbol!" unless key.is_a? Symbol
  #   raise "component '#{key}' defined as constant can have only :application scope!" unless sname == :application
  #   @constants[key] = true
  # end
end

#reset(key) ⇒ Object



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

def reset key
  delete key
  self[key]
end

#runtime_pathObject

:mode, :runtime_path, used in component configuration

  • ‘app/runtime’

  • :development, :test, :production



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

def runtime_path; @runtime_path || raise(":runtime_path not defined!") end

#runtime_path=(runtime_path) ⇒ Object



269
270
271
272
273
# File 'lib/micon/core.rb', line 269

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

#runtime_path?Boolean

Returns:

  • (Boolean)


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

def runtime_path?; !!@runtime_path end

#unregister(key) ⇒ Object



184
185
186
187
# File 'lib/micon/core.rb', line 184

def unregister key
  @metadata.delete key
  # @constants.delete key
end