Class: LanGrove::ClassLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/langrove/ext/class_loader.rb

Class Method Summary collapse

Class Method Details

.create(class_config, logger = nil) ⇒ 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/langrove/ext/class_loader.rb', line 8

def self.create( class_config, logger = nil )
  
  logger.info( "#{self} is loading Class with #{class_config.inspect}" ) unless logger.nil?
  
  #
  # When <config> = {
  # 
  #   :module => 'ModuleName'
  #   :class  => 'ClassName'
  #
  # }
  #
  # Then this will return the constantized
  # definition instance of ClassName as 
  # loaded from the F1RST found .rb file
  # according to:
  # 
  # - lib/module_name/class_name.rb
  # - langrove/module_name/class_name.rb
  #
  # Which then facilitates the following
  # construct:
  #
  # planet = ClassLoader.create(
  # 
  #    :module => 'Planet',
  #    :class  => 'Mercury'
  #
  # ).new( *initializer_parameters )
  #
  
  raise ClassLoaderException.new( 
  
    "class_config requires :module" 
    
  ) unless class_config.has_key? :module
  
  raise ClassLoaderException.new( 
  
    "class_config requires :class" 
    
  ) unless class_config.has_key? :class
  
  
  module_name = class_config[:module]
  class_name  = class_config[:class]
  
  
  #
  # SIGNIFICANT DECISION
  #
  # - Late binding to the extent of also calling
  #   to require the actual class.rb file could 
  #   potentially be avoided by
  # 
  #    << using this layer in the abstraction >>
  #
  #   to do the necessary requiring for the specific
  #   daemon being spawned.
  #
  # - Obviously there are downsides to eval...
  #
  # - But there are upsides to having this layer
  #   totally aliteral - it leaves the window open
  #   to the later posibility of collecting the class
  #   definition itself from across the network. 
  #
  # 
  #   Which was the cental purpose behind daemons
  #   by configuration in the first place.
  #
  #   Taking latebinding to a whole new level...
  #
  
  
  #
  # First try local implementation root
  #
  
  exception = nil
  
  location = nil
  
  begin
    
    location = "#{module_name.underscore}/#{class_name.underscore}"
    
    eval "require '#{location}'"
    
    return Object.const_get( module_name ).const_get( class_name )
    
  rescue LoadError => e
    
    exception = e
    
    logger.error "Missing class definition in lib/#{location}.rb" unless logger.nil?
    
  #rescue Exception => e 
  #  
  #  #
  #  # Incase of more... (discovery phase)
  #  #
  #
  
    
  end
  
  #
  # Fall back to langrove gem lib
  #
  
  begin
    
    location = "langrove/#{module_name.underscore}/#{class_name.underscore}"
    
    eval "require '#{location}'"
    
    return LanGrove.const_get( module_name ).const_get( class_name )
    
  rescue Exception => e
    
    #
    # Raise from the original exception to
    # inform the local implementation
    # it is missing a module/class .rb
    # "no such file 'module/class"
    #
    # And not confuse the issue by raising
    # "no such file 'langrove/module/class"
    #
    raise ClassLoaderException.new "#{exception.message}.rb"
    
  end
  
end