zh / tamanegi

RSS/Atom feeds aggregator, powered by Ramaze. Using Sequel for ORM.

This URL has Read+Write access

tamanegi / lib / configuration.rb
100644 178 lines (151 sloc) 4.009 kb
1
2
3
4
5
6
7
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
class Configuration
  Version = '0.0.5'
  def Configuration.version() Version end
 
  Path = [
    if defined? CONFIGURATION_PATH
      CONFIGURATION_PATH
    else
      ENV['CONFIGURATION_PATH']
    end
  ].compact.flatten.join(File::PATH_SEPARATOR).split(File::PATH_SEPARATOR)
 
  Table = Hash.new
  Error = Class.new StandardError
  Import = Class.new Error
 
  module ClassMethods
    def for name, options = nil, &block
      name = name.to_s
      if Table.has_key?(name)
        if options or block
          configuration = Table[name]
          Table[name] = DSL.evaluate(configuration, options || {}, &block)
        else
          Table[name]
        end
      else
        if options or block
          Table[name] = new name, options || {}, &block
        else
          load name
        end
      end
    end
 
    def path *value
      return self.path = value.first unless value.empty?
      Path
    end
 
    def path= value
      Path.clear
      Path.replace [value].compact.flatten.join(File::PATH_SEPARATOR).split(File::PATH_SEPARATOR)
    end
 
    def load name
      name = name.to_s
      name = name + '.rb' unless name[%r/\.rb$/]
key = name.sub %r/\.rb$/, ''
load_path = $LOAD_PATH.dup
begin
$LOAD_PATH.replace(path + load_path)
::Kernel.load name
ensure
$LOAD_PATH.replace load_path
end
Table[key]
end
end
send :extend, ClassMethods
 
module InstanceMethods
attr 'name'
 
def initialize *argv, &block
options = Hash === argv.last ? argv.pop : Hash.new
@name = argv.shift
DSL.evaluate(self, options, &block)
end
 
def method_missing m, *a, &b
return(Pure[@__parent].send m, *a, &b) rescue super if @__parent
super
end
end
send :include, InstanceMethods
 
 
class DSL
instance_methods.each do |m|
undef_method m unless m[%r/^__/]
end
 
Kernel.methods.each do |m|
next if m[%r/^__/]
module_eval <<-code
def #{ m }(*a, &b)
method_missing '#{ m }', *a, &b
end
code
end
 
def Send(m, *a, &b)
Method(m).call(*a, &b)
end
 
def Method m
@__configuration.method(m)
end
 
def self.evaluate configuration, options = {}, &block
dsl = new configuration
Pure[dsl].instance_eval &block if block
options.each{|key, value| Pure[dsl].send key, value}
Pure[dsl].instance_eval{ @__configuration }
end
 
def initialize configuration, &block
@__configuration = configuration
@__singleton_class =
class << @__configuration
self
end
end
 
def __configuration__
@__configuration
end
 
def method_missing m, *a, &b
if(a.empty? and b.nil?)
return Pure[@__configuration].send(m, *a, &b)
end
if b
raise ArgumentError unless a.empty?
parent = @__configuration
name = m.to_s
configuration =
if @__configuration.respond_to?(name) and Configuration === @__configuration.send(name)
@__configuration.send name
else
Configuration.new name
end
Pure[configuration].instance_eval{ @__parent = parent }
DSL.evaluate configuration, &b
value = configuration
end
unless a.empty?
value = a.size == 1 ? a.first : a
end
@__singleton_class.module_eval do
define_method(m){ value }
end
end
end
 
class Pure
Instance_Methods = Hash.new
 
::Object.instance_methods.each do |m|
Instance_Methods[m.to_s] = ::Object.instance_method m
undef_method m unless m[%r/^__/]
    end
 
    def method_missing m, *a, &b
      Instance_Methods[m.to_s].bind(@object).call(*a, &b)
    end
 
    def initialize object
      @object = object
    end
 
    def Pure.[] object
      new object
    end
  end
end
 
def Configuration(*a, &b)
  if a.empty? and b.nil?
    const_get :Configuration
  else
    Configuration.new(*a, &b)
  end
end