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