alki 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +29 -0
- data/alki.gemspec +24 -0
- data/lib/alki/class_builder.rb +41 -0
- data/lib/alki/dsl_builder.rb +43 -0
- data/lib/alki/group_builder.rb +25 -0
- data/lib/alki/group_dsl.rb +98 -0
- data/lib/alki/loader.rb +32 -0
- data/lib/alki/overlay_delegator.rb +33 -0
- data/lib/alki/package.rb +33 -0
- data/lib/alki/package_builder.rb +2 -0
- data/lib/alki/package_executor.rb +120 -0
- data/lib/alki/package_processor.rb +167 -0
- data/lib/alki/service_delegator.rb +14 -0
- data/lib/alki/standard_package.rb +19 -0
- data/lib/alki/test.rb +28 -0
- data/lib/alki/util.rb +35 -0
- data/lib/alki/version.rb +3 -0
- data/lib/alki.rb +27 -0
- data/test/feature/create_package_test.rb +17 -0
- data/test/fixtures/config.rb +6 -0
- data/test/fixtures/example/config/handlers.rb +29 -0
- data/test/fixtures/example/config/package.rb +35 -0
- data/test/fixtures/example/config/settings.rb +11 -0
- data/test/fixtures/example/lib/array_output.rb +11 -0
- data/test/fixtures/example/lib/echo_handler.rb +9 -0
- data/test/fixtures/example/lib/example.rb +3 -0
- data/test/fixtures/example/lib/num_handler.rb +11 -0
- data/test/fixtures/example/lib/range_handler.rb +11 -0
- data/test/fixtures/example/lib/switch_handler.rb +9 -0
- data/test/integration/class_builder_test.rb +130 -0
- data/test/integration/loader_test.rb +36 -0
- data/test/test_helper.rb +1 -0
- data/test/unit/application_settings_test.rb +56 -0
- data/test/unit/application_test.rb +159 -0
- data/test/unit/package_processor_test.rb +319 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: acebb8f2a073f60c659eb7b994778f3717c140c9
|
4
|
+
data.tar.gz: c6bf4c35dbe97001bfed4b772a84e811b7200b93
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 623bacc9055973a92a710f2a7fe7235cdea0da93d5f434445b9b931ccc2c4ea51f261ba6715f19d95a5bd90ac5b496e05ce3f0e127877d1e45814863b0bd03d2
|
7
|
+
data.tar.gz: f33554183dc94171bb8191908745f218cf6bc5215e2125a9d9de4fc9cce1708a25799670e00833050fa83d54201fb02fb4f290f665881094f598870761c5476e
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
*.iml
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Matt Edlefsen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.name = 'test:unit'
|
6
|
+
t.pattern = "test/unit/*_test.rb"
|
7
|
+
end
|
8
|
+
|
9
|
+
Rake::TestTask.new do |t|
|
10
|
+
t.name = 'test:feature'
|
11
|
+
t.pattern = "test/feature/*_test.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
Rake::TestTask.new do |t|
|
15
|
+
t.name = 'test:integration'
|
16
|
+
t.pattern = "test/integration/*_test.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
Rake::TestTask.new do |t|
|
20
|
+
t.name = 'test:page'
|
21
|
+
t.pattern = "test/page/*_test.rb"
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::TestTask.new do |t|
|
25
|
+
t.name = 'test'
|
26
|
+
t.pattern = "test/*/*_test.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
task default: [:test]
|
data/alki.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'alki/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "alki"
|
8
|
+
spec.version = Alki::VERSION
|
9
|
+
spec.authors = ["Matt Edlefsen"]
|
10
|
+
spec.email = ["matt@xforty.com"]
|
11
|
+
spec.summary = %q{Base library for building applications.}
|
12
|
+
spec.description = %q{Base library for building applications. Provides tools for organizing and connection application units.}
|
13
|
+
spec.homepage = "https://gitlab.xforty.com/matt/base-alki"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency "rake", '~> 10.0'
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'alki/dsl_builder'
|
2
|
+
|
3
|
+
module Alki
|
4
|
+
class ClassBuilder
|
5
|
+
def initialize(*dsl_factories)
|
6
|
+
@dsl_factories = dsl_factories.flatten
|
7
|
+
end
|
8
|
+
|
9
|
+
def build(name=nil,&blk)
|
10
|
+
self.class.build(name,@dsl_factories,&blk)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.build(name=nil,dsl_factories,&blk)
|
14
|
+
Class.new.tap do |c|
|
15
|
+
builder = -> {
|
16
|
+
Module.new.tap do |m|
|
17
|
+
m.define_singleton_method :klass do
|
18
|
+
c
|
19
|
+
end
|
20
|
+
end
|
21
|
+
}
|
22
|
+
m = DslBuilder.build(c,dsl_factories,
|
23
|
+
builder: builder,exec: :class_exec,
|
24
|
+
&blk)
|
25
|
+
c.include m
|
26
|
+
if name
|
27
|
+
*ans, ln = name.to_s.split(/::/)
|
28
|
+
parent = Object
|
29
|
+
ans.each do |a|
|
30
|
+
unless parent.const_defined? a
|
31
|
+
parent.const_set a, Module.new
|
32
|
+
end
|
33
|
+
parent = parent.const_get a
|
34
|
+
end
|
35
|
+
|
36
|
+
parent.const_set ln, c
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Alki
|
2
|
+
class DslBuilder
|
3
|
+
def initialize(*dsl_factories,builder: nil, exec: nil)
|
4
|
+
@builder = builder
|
5
|
+
@exec = exec
|
6
|
+
@dsl_factories = dsl_factories.flatten
|
7
|
+
end
|
8
|
+
|
9
|
+
def build(obj,&blk)
|
10
|
+
self.class.build(obj,@dsl_factories,
|
11
|
+
builder: @builder,
|
12
|
+
exec: @exec,
|
13
|
+
&blk)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build(obj,dsl_factories,builder: nil, exec: nil, &blk)
|
17
|
+
builder ||= Object.method(:new)
|
18
|
+
exec ||= :instance_exec
|
19
|
+
unless dsl_factories.is_a?(Array)
|
20
|
+
dsl_factories = [dsl_factories]
|
21
|
+
end
|
22
|
+
builder = builder.call
|
23
|
+
dsls = []
|
24
|
+
dsl_factories.each do |dsl_factory|
|
25
|
+
if dsl_factory.respond_to? :new_dsl
|
26
|
+
dsl = dsl_factory.new_dsl obj
|
27
|
+
else
|
28
|
+
dsl = dsl_factory.new obj
|
29
|
+
end
|
30
|
+
dsl.dsl_methods.each do |method_name|
|
31
|
+
method = dsl.method(method_name)
|
32
|
+
builder.define_singleton_method method_name do |*args,&blk|
|
33
|
+
method.call *args, &blk
|
34
|
+
end
|
35
|
+
end
|
36
|
+
dsls << dsl
|
37
|
+
end
|
38
|
+
builder.send(exec,&blk)
|
39
|
+
dsls.each {|dsl| dsl.finalize if dsl.respond_to? :finalize }
|
40
|
+
builder
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'alki/group_dsl'
|
2
|
+
require 'alki/dsl_builder'
|
3
|
+
|
4
|
+
module Alki
|
5
|
+
class GroupBuilder
|
6
|
+
def self.build(loader,obj = {},&dsl)
|
7
|
+
Alki::GroupBuilder.new(loader).build(obj,&dsl)
|
8
|
+
obj
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(loader)
|
12
|
+
@loader = loader
|
13
|
+
@builder = Alki::DslBuilder.new(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_dsl(obj)
|
17
|
+
GroupDsl.new(obj,loader: @loader, group_builder: @builder)
|
18
|
+
end
|
19
|
+
|
20
|
+
def build(group={},&dsl)
|
21
|
+
@builder.build(group,&dsl)
|
22
|
+
group
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'alki/util'
|
2
|
+
|
3
|
+
module Alki
|
4
|
+
class GroupDsl
|
5
|
+
def initialize(root,group_builder:,loader:)
|
6
|
+
@root = root
|
7
|
+
@group_builder = group_builder
|
8
|
+
@loader = loader
|
9
|
+
end
|
10
|
+
|
11
|
+
def dsl_methods
|
12
|
+
[:set,:service,:factory,:load,:import,:group,:overlay,:clear_overlays]
|
13
|
+
end
|
14
|
+
|
15
|
+
def set(name,value=nil,&blk)
|
16
|
+
service name, &(blk || -> { value })
|
17
|
+
end
|
18
|
+
|
19
|
+
def service(name,&blk)
|
20
|
+
name = name.to_sym
|
21
|
+
@root[name] = {
|
22
|
+
type: :service,
|
23
|
+
block: blk
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def factory(name,&blk)
|
28
|
+
name = name.to_sym
|
29
|
+
@root[name] = {
|
30
|
+
type: :factory,
|
31
|
+
block: blk
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def import(name)
|
36
|
+
instance_exec &@loader.load(name.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load(name)
|
40
|
+
group(name.to_sym) do
|
41
|
+
import(name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def package(name,pkg,klass=nil,&blk)
|
46
|
+
if pkg.is_a? String
|
47
|
+
require pkg
|
48
|
+
if klass == nil
|
49
|
+
pkg = Alki::Util.classify(pkg)
|
50
|
+
else
|
51
|
+
pkg = klass
|
52
|
+
end
|
53
|
+
end
|
54
|
+
if pkg.is_a? Class
|
55
|
+
pkg = pkg.new
|
56
|
+
end
|
57
|
+
if pkg.response_to? :package_definition
|
58
|
+
pkg = pkg.package_definition
|
59
|
+
end
|
60
|
+
unless pkg.is_a? Hash
|
61
|
+
raise "Invalid package: #{pkg.inspect}"
|
62
|
+
end
|
63
|
+
name = name.to_sym
|
64
|
+
overrides = {}
|
65
|
+
@group_builder.build(overrides,&blk) if blk
|
66
|
+
overrides[:original] = {
|
67
|
+
type: :package,
|
68
|
+
children: pkg,
|
69
|
+
overrides: {}
|
70
|
+
}
|
71
|
+
@root[name] = {
|
72
|
+
type: :package,
|
73
|
+
children: pkg,
|
74
|
+
overrides: overrides
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def group(name,&blk)
|
79
|
+
name = name.to_sym
|
80
|
+
children = {}
|
81
|
+
@group_builder.build(children,&blk)
|
82
|
+
@root[name] = {
|
83
|
+
type: :group,
|
84
|
+
children: children
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def overlay(&blk)
|
89
|
+
@root['overlays'] ||= []
|
90
|
+
@root['overlays'] << blk
|
91
|
+
end
|
92
|
+
|
93
|
+
def clear_overlays
|
94
|
+
@root['overlays'] ||= []
|
95
|
+
@root['overlays'] << :clear
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/alki/loader.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Alki
|
2
|
+
class Loader
|
3
|
+
def self.load(config_file)
|
4
|
+
Fiber.new do
|
5
|
+
Kernel.load config_file
|
6
|
+
Thread.current[:alki_loader_current]
|
7
|
+
end.resume
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(root_dir)
|
11
|
+
@root_dir = root_dir
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_all
|
15
|
+
Dir[File.join(@root_dir,'**','*.rb')].inject({}) do |h,path|
|
16
|
+
file = path.gsub(File.join(@root_dir,''),'').gsub(/\.rb$/,'')
|
17
|
+
h.merge!(file => Loader.load(path))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(file)
|
22
|
+
Loader.load File.expand_path("#{file}.rb",@root_dir)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Kernel
|
28
|
+
def Alki(&blk)
|
29
|
+
Thread.current[:alki_loader_current] = blk if blk
|
30
|
+
::Alki
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Alki
|
2
|
+
class OverlayDelegator
|
3
|
+
def initialize(name,obj,overlay)
|
4
|
+
@name = name
|
5
|
+
@obj = obj
|
6
|
+
@overlay = overlay
|
7
|
+
@key = :"#{obj.object_id}:#{overlay.object_id}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def respond_to_missing(method,include_private = false)
|
11
|
+
unless Thread.current[@key]
|
12
|
+
Thread.current[@key] = true
|
13
|
+
if @overlay.respond_to? :overlay_respond_to?
|
14
|
+
@overlay.overlay_respond_to? @obj, method, include_private
|
15
|
+
else
|
16
|
+
@obj.respond_to? method, include_private
|
17
|
+
end
|
18
|
+
Thread.current[@key] = false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(method,*args,&blk)
|
23
|
+
if Thread.current[@key]
|
24
|
+
res = @obj.send method, *args, &blk
|
25
|
+
else
|
26
|
+
Thread.current[@key] = true
|
27
|
+
res = @overlay.call @name, @obj, method, *args, &blk
|
28
|
+
Thread.current[@key] = false
|
29
|
+
end
|
30
|
+
res
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/alki/package.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'alki/package_executor'
|
2
|
+
require 'alki/package_processor'
|
3
|
+
|
4
|
+
module Alki
|
5
|
+
class Package
|
6
|
+
def initialize(package_definition)
|
7
|
+
@def = package_definition
|
8
|
+
@cache = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def root
|
12
|
+
@root ||= __executor__.call @def, @cache, []
|
13
|
+
end
|
14
|
+
|
15
|
+
def package_definition
|
16
|
+
@def
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to_missing?(name,include_all)
|
20
|
+
root.respond_to? name
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name,*args,&blk)
|
24
|
+
root.send name, *args, &blk
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def __executor__
|
30
|
+
@executor ||= Alki::PackageExecutor.new Alki::PackageProcessor.new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'alki/service_delegator'
|
2
|
+
require 'alki/overlay_delegator'
|
3
|
+
|
4
|
+
module Alki
|
5
|
+
class PackageExecutor
|
6
|
+
def initialize(processor)
|
7
|
+
@processor = processor
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(pkg,cache,path,*args,&blk)
|
11
|
+
elem = @processor.lookup(pkg,path)
|
12
|
+
triple = [pkg,cache,elem]
|
13
|
+
case elem[:type]
|
14
|
+
when :service
|
15
|
+
service triple, path, *args
|
16
|
+
when :factory
|
17
|
+
factory triple, path, *args, &blk
|
18
|
+
when :group
|
19
|
+
group triple, *args
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def service(triple,path)
|
24
|
+
pkg,cache,elem = triple
|
25
|
+
unless cache[path]
|
26
|
+
with_scope_context(triple) do |ctx,blk|
|
27
|
+
cache[path] = apply_overlays triple,path, ctx.instance_exec(&blk)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
cache[path]
|
31
|
+
end
|
32
|
+
|
33
|
+
def apply_overlays((pkg,cache,elem),path,obj)
|
34
|
+
elem[:overlays].inject(obj) do |obj,overlay_elem|
|
35
|
+
unless cache[overlay_elem[:block]]
|
36
|
+
with_scope_context([pkg,cache,overlay_elem]) do |ctx,blk|
|
37
|
+
cache[overlay_elem[:block]] = ctx.instance_exec(&blk)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
local_path = path[overlay_elem[:scope][:root].size..-1].join('.')
|
41
|
+
Alki::OverlayDelegator.new local_path,obj, cache[overlay_elem[:block]]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def factory(triple,path,*args,&blk)
|
46
|
+
pkg,cache,elem = triple
|
47
|
+
unless cache[path]
|
48
|
+
with_scope_context(triple) do |ctx,blk|
|
49
|
+
cache[path] = ctx.instance_exec(&blk)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
cache[path].call *args, &blk
|
53
|
+
end
|
54
|
+
|
55
|
+
def group((pkg,cache,elem))
|
56
|
+
proc = -> (name,*args,&blk) {
|
57
|
+
call pkg, cache, elem[:children][name], *args, &blk
|
58
|
+
}
|
59
|
+
|
60
|
+
GroupContext.new(proc,elem[:children].keys)
|
61
|
+
end
|
62
|
+
|
63
|
+
def with_scope_context((pkg,cache,elem))
|
64
|
+
proc = -> (name,*args,&blk) {
|
65
|
+
call pkg, cache, elem[:scope][name], *args, &blk
|
66
|
+
}
|
67
|
+
|
68
|
+
yield ServiceContext.new(proc,elem[:scope].keys), elem[:block]
|
69
|
+
end
|
70
|
+
|
71
|
+
class Context
|
72
|
+
def initialize(executor,scope)
|
73
|
+
@executor = executor
|
74
|
+
@scope = scope
|
75
|
+
end
|
76
|
+
|
77
|
+
def respond_to_missing?(name,include_all)
|
78
|
+
@scope.include? name
|
79
|
+
end
|
80
|
+
|
81
|
+
def method_missing(name,*args,&blk)
|
82
|
+
if @scope.include? name
|
83
|
+
@executor.call name, *args, &blk
|
84
|
+
else
|
85
|
+
super
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class ServiceContext < Context
|
91
|
+
def lookup(path)
|
92
|
+
unless path.is_a?(String) or path.is_a?(Symbol)
|
93
|
+
raise ArgumentError.new("lookup can only take Strings or Symbols")
|
94
|
+
end
|
95
|
+
path.to_s.split('.').inject(self) do |group,name|
|
96
|
+
raise "Invalid lookup path" unless group.is_a? Context
|
97
|
+
group.send name.to_sym
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def lazy(path)
|
102
|
+
unless path.is_a?(String) or path.is_a?(Symbol)
|
103
|
+
raise ArgumentError.new("lazy can only take Strings or Symbols")
|
104
|
+
end
|
105
|
+
Alki::ServiceDelegator.new root, path
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class GroupContext < Context
|
110
|
+
def lookup(path)
|
111
|
+
unless path.is_a?(String) or path.is_a?(Symbol)
|
112
|
+
raise ArgumentError.new("lookup can only take Strings or Symbols")
|
113
|
+
end
|
114
|
+
path.to_s.split('.').inject(self) do |group,name|
|
115
|
+
group.send name.to_sym
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|