scorpion-ioc 0.3.1 → 0.4.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 +4 -4
- data/.gitignore +2 -1
- data/.rspec +2 -1
- data/README.md +111 -44
- data/lib/scorpion/attribute.rb +0 -1
- data/lib/scorpion/attribute_set.rb +15 -7
- data/lib/scorpion/dependency/argument_dependency.rb +25 -0
- data/lib/scorpion/{prey/builder_prey.rb → dependency/builder_dependency.rb} +8 -8
- data/lib/scorpion/dependency/captured_dependency.rb +44 -0
- data/lib/scorpion/dependency/class_dependency.rb +25 -0
- data/lib/scorpion/dependency/module_dependency.rb +14 -0
- data/lib/scorpion/dependency.rb +137 -0
- data/lib/scorpion/dependency_map.rb +135 -0
- data/lib/scorpion/hunt.rb +158 -0
- data/lib/scorpion/hunter.rb +21 -20
- data/lib/scorpion/locale/en.yml +5 -1
- data/lib/scorpion/{king.rb → object.rb} +72 -53
- data/lib/scorpion/object_constructor.rb +55 -0
- data/lib/scorpion/rails/active_record/association.rb +65 -0
- data/lib/scorpion/rails/active_record/model.rb +28 -0
- data/lib/scorpion/rails/active_record/relation.rb +66 -0
- data/lib/scorpion/rails/active_record.rb +21 -0
- data/lib/scorpion/rails/controller.rb +22 -62
- data/lib/scorpion/rails/job.rb +30 -0
- data/lib/scorpion/rails/nest.rb +86 -0
- data/lib/scorpion/rails/railtie.rb +16 -0
- data/lib/scorpion/rails.rb +4 -0
- data/lib/scorpion/rspec/helper.rb +25 -0
- data/lib/scorpion/rspec.rb +17 -0
- data/lib/scorpion/stinger.rb +69 -0
- data/lib/scorpion/version.rb +1 -1
- data/lib/scorpion.rb +91 -44
- data/scorpion.gemspec +1 -1
- data/spec/internal/app/models/author.rb +17 -0
- data/spec/internal/app/models/todo.rb +14 -0
- data/spec/internal/db/schema.rb +12 -1
- data/spec/lib/scorpion/dependency/argument_dependency_spec.rb +18 -0
- data/spec/lib/scorpion/dependency/builder_dependency_spec.rb +41 -0
- data/spec/lib/scorpion/dependency/module_dependency_spec.rb +16 -0
- data/spec/lib/scorpion/dependency_map_spec.rb +108 -0
- data/spec/lib/scorpion/dependency_spec.rb +131 -0
- data/spec/lib/scorpion/hunt_spec.rb +93 -0
- data/spec/lib/scorpion/hunter_spec.rb +53 -14
- data/spec/lib/scorpion/object_constructor_spec.rb +49 -0
- data/spec/lib/scorpion/object_spec.rb +214 -0
- data/spec/lib/scorpion/rails/active_record/association_spec.rb +26 -0
- data/spec/lib/scorpion/rails/active_record/model_spec.rb +33 -0
- data/spec/lib/scorpion/rails/active_record/relation_spec.rb +72 -0
- data/spec/lib/scorpion/rails/controller_spec.rb +9 -9
- data/spec/lib/scorpion/rails/job_spec.rb +34 -0
- data/spec/lib/scorpion/rspec/helper_spec.rb +44 -0
- data/spec/lib/scorpion_spec.rb +0 -35
- data/spec/spec_helper.rb +1 -0
- metadata +54 -26
- data/lib/scorpion/hunting_map.rb +0 -139
- data/lib/scorpion/prey/captured_prey.rb +0 -44
- data/lib/scorpion/prey/class_prey.rb +0 -13
- data/lib/scorpion/prey/hunted_prey.rb +0 -14
- data/lib/scorpion/prey/module_prey.rb +0 -14
- data/lib/scorpion/prey.rb +0 -94
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/lib/scorpion/hunting_map_spec.rb +0 -126
- data/spec/lib/scorpion/instance_spec.rb +0 -5
- data/spec/lib/scorpion/king_spec.rb +0 -198
- data/spec/lib/scorpion/prey/builder_prey_spec.rb +0 -42
- data/spec/lib/scorpion/prey/module_prey_spec.rb +0 -16
- data/spec/lib/scorpion/prey_spec.rb +0 -76
@@ -0,0 +1,137 @@
|
|
1
|
+
module Scorpion
|
2
|
+
# Dependency that can be injected into a {Scorpion::Object} by a {Scorpion}.
|
3
|
+
class Dependency
|
4
|
+
|
5
|
+
require 'scorpion/dependency/captured_dependency'
|
6
|
+
require 'scorpion/dependency/class_dependency'
|
7
|
+
require 'scorpion/dependency/module_dependency'
|
8
|
+
require 'scorpion/dependency/builder_dependency'
|
9
|
+
require 'scorpion/dependency/argument_dependency'
|
10
|
+
|
11
|
+
# ============================================================================
|
12
|
+
# @!group Attributes
|
13
|
+
#
|
14
|
+
|
15
|
+
# @!attribute
|
16
|
+
# @return [Class,Module,Symbol] contract describing the desired behavior of the dependency.
|
17
|
+
attr_reader :contract
|
18
|
+
|
19
|
+
# @!attribute
|
20
|
+
# @return [Array<Symbol>] the traits available on the dependency.
|
21
|
+
attr_reader :traits
|
22
|
+
|
23
|
+
#
|
24
|
+
# @!endgroup Attributes
|
25
|
+
|
26
|
+
def initialize( contract, traits = nil )
|
27
|
+
@contract = contract
|
28
|
+
@traits = Set.new( Array( traits ) )
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean] if the dependency satisfies the required contract and traits.
|
32
|
+
def satisfies?( contract, traits = nil )
|
33
|
+
satisfies_contract?( contract ) && satisfies_traits?( traits )
|
34
|
+
end
|
35
|
+
|
36
|
+
# Fetch an instance of the dependency.
|
37
|
+
# @param [Hunt] the hunting context.
|
38
|
+
# @return [Object] the hunted dependency.
|
39
|
+
def fetch( hunt )
|
40
|
+
fail "Not Implemented"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Release the dependency, freeing up any long held resources.
|
44
|
+
def release
|
45
|
+
end
|
46
|
+
|
47
|
+
# Replicate the Dependency.
|
48
|
+
# @return [Dependency] a replication of the dependency.
|
49
|
+
def replicate
|
50
|
+
dup
|
51
|
+
end
|
52
|
+
|
53
|
+
def ==( other )
|
54
|
+
return unless other
|
55
|
+
self.class == other.class &&
|
56
|
+
contract == other.contract &&
|
57
|
+
traits == other.traits
|
58
|
+
end
|
59
|
+
alias_method :eql?, :==
|
60
|
+
|
61
|
+
def hash
|
62
|
+
self.class.hash ^
|
63
|
+
contract.hash ^
|
64
|
+
traits.hash
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# @return [Boolean] true if the pray satisfies the given contract.
|
70
|
+
def satisfies_contract?( contract )
|
71
|
+
if self.contract.is_a? Symbol
|
72
|
+
self.contract == contract
|
73
|
+
else
|
74
|
+
self.contract <= contract
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [Boolean] true if the pray satisfies the given contract.
|
79
|
+
def satisfies_traits?( traits )
|
80
|
+
return true if traits.blank?
|
81
|
+
|
82
|
+
Array( traits ).all? do |trait|
|
83
|
+
case trait
|
84
|
+
when Symbol then self.traits.include? trait
|
85
|
+
when Module then self.contract <= trait
|
86
|
+
else fail ArgumentError, "Unsupported trait"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class << self
|
92
|
+
|
93
|
+
# Define dependency based on the desired contract and traits.
|
94
|
+
# @return [Dependency] the defined dependency.
|
95
|
+
def define( contract, traits = nil , &builder )
|
96
|
+
options, traits = extract_options!( traits )
|
97
|
+
|
98
|
+
if options.key?( :return )
|
99
|
+
Scorpion::Dependency::BuilderDependency.new( contract, traits ) do
|
100
|
+
options[:return]
|
101
|
+
end
|
102
|
+
elsif with = options[:with]
|
103
|
+
Scorpion::Dependency::BuilderDependency.new( contract, traits, with )
|
104
|
+
elsif block_given?
|
105
|
+
Scorpion::Dependency::BuilderDependency.new( contract, traits, builder )
|
106
|
+
elsif contract.respond_to?( :create )
|
107
|
+
Scorpion::Dependency::BuilderDependency.new( contract, traits ) do |scorpion,*args,&block|
|
108
|
+
contract.create scorpion, *args, &block
|
109
|
+
end
|
110
|
+
else
|
111
|
+
dependency_class( contract ).new( contract, traits, &builder )
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def extract_options!( traits )
|
117
|
+
case traits
|
118
|
+
when Hash then return [ traits, nil ]
|
119
|
+
when Array then
|
120
|
+
if traits.last.is_a? Hash
|
121
|
+
return [ traits.pop, traits ]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
[ {}, traits]
|
126
|
+
end
|
127
|
+
|
128
|
+
def dependency_class( contract, &builder )
|
129
|
+
return Scorpion::Dependency::ClassDependency if contract.is_a? Class
|
130
|
+
return Scorpion::Dependency::ModuleDependency if contract.is_a? Module
|
131
|
+
|
132
|
+
raise Scorpion::BuilderRequiredError
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Scorpion
|
2
|
+
# {#chart} available {Dependency} and {#find} them based on desired
|
3
|
+
# {Scorpion::Attribute attributes}.
|
4
|
+
class DependencyMap
|
5
|
+
include Enumerable
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# ============================================================================
|
9
|
+
# @!group Attributes
|
10
|
+
#
|
11
|
+
|
12
|
+
# @return [Scorpion] the scorpion that created the map.
|
13
|
+
attr_reader :scorpion
|
14
|
+
|
15
|
+
# @return [Set] the set of dependency charted on this map.
|
16
|
+
attr_reader :dependency_set
|
17
|
+
private :dependency_set
|
18
|
+
|
19
|
+
# @return [Set] the set of dependencies charted on this map that is shared
|
20
|
+
# with all child dependencies.
|
21
|
+
attr_reader :shared_dependency_set
|
22
|
+
private :shared_dependency_set
|
23
|
+
|
24
|
+
# @return [Set] the active dependency set either {#dependency_set} or {#shared_dependency_set}
|
25
|
+
attr_reader :active_dependency_set
|
26
|
+
private :active_dependency_set
|
27
|
+
|
28
|
+
#
|
29
|
+
# @!endgroup Attributes
|
30
|
+
|
31
|
+
def initialize( scorpion )
|
32
|
+
@scorpion = scorpion
|
33
|
+
@dependency_set = @active_dependency_set = []
|
34
|
+
@shared_dependency_set = []
|
35
|
+
end
|
36
|
+
|
37
|
+
# Find {Dependency} that matches the requested `contract` and `traits`.
|
38
|
+
# @param [Class,Module,Symbol] contract describing the desired behavior of the dependency.
|
39
|
+
# @param [Array<Symbol>] traits found on the {Dependency}.
|
40
|
+
# @return [Dependency] the dependency matching the attribute.
|
41
|
+
def find( contract, traits = nil )
|
42
|
+
dependency_set.find{ |p| p.satisfies?( contract, traits ) } ||
|
43
|
+
shared_dependency_set.find{ |p| p.satisfies?( contract, traits ) }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Chart the {Dependency} that this hunting map can {#find}.
|
47
|
+
#
|
48
|
+
# The block is executed in the context of DependencyMap if the block does not
|
49
|
+
# accept any arguments so that {#hunt_for}, {#capture} and {#share} can be
|
50
|
+
# called as methods.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
#
|
54
|
+
# cache = {}
|
55
|
+
# chart do
|
56
|
+
# self #=> DependencyMap
|
57
|
+
# hunt_for Repository
|
58
|
+
# capture Cache, return: cache # => NoMethodError
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# chart do |map|
|
62
|
+
# map.hunt_for Repository
|
63
|
+
# map.capture Cache, return: cache # => No problem
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# @return [self]
|
67
|
+
def chart( &block )
|
68
|
+
return unless block_given?
|
69
|
+
|
70
|
+
if block.arity == 1
|
71
|
+
yield self
|
72
|
+
else
|
73
|
+
instance_eval &block
|
74
|
+
end
|
75
|
+
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# Define {Dependency} that can be found on this map by `contract` and `traits`.
|
80
|
+
#
|
81
|
+
# If a block is given, it will be used build the actual instances of the
|
82
|
+
# dependency for the {Scorpion}.
|
83
|
+
#
|
84
|
+
# @param [Class,Module,Symbol] contract describing the desired behavior of the dependency.
|
85
|
+
# @param [Array<Symbol>] traits found on the {Dependency}.
|
86
|
+
# @return [Dependency] the dependency to be hunted for.
|
87
|
+
def hunt_for( contract, traits = nil, &builder )
|
88
|
+
active_dependency_set.unshift define_dependency( contract, traits, &builder )
|
89
|
+
end
|
90
|
+
|
91
|
+
# Captures a single dependency and returns the same instance fore each request
|
92
|
+
# for the resource.
|
93
|
+
# @see #hunt_for
|
94
|
+
# @return [Dependency] the dependency to be hunted for.
|
95
|
+
def capture( contract, traits = nil, &builder )
|
96
|
+
active_dependency_set.unshift Dependency::CapturedDependency.new( define_dependency( contract, traits, &builder ) )
|
97
|
+
end
|
98
|
+
alias_method :singleton, :capture
|
99
|
+
|
100
|
+
# Share dependencies defined within the block with all child scorpions.
|
101
|
+
# @return [Dependency] the dependency to be hunted for.
|
102
|
+
def share( &block )
|
103
|
+
old_set = active_dependency_set
|
104
|
+
@active_dependency_set = shared_dependency_set
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
@active_dependency_set = old_set
|
108
|
+
end
|
109
|
+
|
110
|
+
# @visibility private
|
111
|
+
def each( &block )
|
112
|
+
dependency_set.each &block
|
113
|
+
end
|
114
|
+
delegate [ :empty?, :blank?, :present? ] => :dependency_set
|
115
|
+
|
116
|
+
# Replicates the dependency in `other_map` into this map.
|
117
|
+
# @param [Scorpion::DependencyMap] other_map to replicate from.
|
118
|
+
# @return [self]
|
119
|
+
def replicate_from( other_map )
|
120
|
+
other_map.each do |dependency|
|
121
|
+
if replica = dependency.replicate
|
122
|
+
dependency_set << replica
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def define_dependency( contract, traits, &builder )
|
132
|
+
Dependency.define contract, traits, &builder
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Scorpion
|
2
|
+
# Captures state for a specific hunt so that constructor arguments can be
|
3
|
+
# shared with child dependencies.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
#
|
7
|
+
# class Service
|
8
|
+
# depend_on do
|
9
|
+
# options UserOptions
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def initialize( user )
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# class UserOptions
|
17
|
+
#
|
18
|
+
# depend_on do
|
19
|
+
# user User
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# user = User.find 123
|
24
|
+
# service = scorpion.fetch Service, user
|
25
|
+
# service.options.user # => user
|
26
|
+
class Hunt
|
27
|
+
extend Forwardable
|
28
|
+
|
29
|
+
# ============================================================================
|
30
|
+
# @!group Attributes
|
31
|
+
#
|
32
|
+
|
33
|
+
# @!attribute
|
34
|
+
# @return [Scorpion] scorpion used to fetch uncaptured dependency.
|
35
|
+
attr_reader :scorpion
|
36
|
+
|
37
|
+
# @!attribute
|
38
|
+
# @return [Array<Array>] the stack of trips conducted by the hunt to help
|
39
|
+
# resolve child dependencies.
|
40
|
+
attr_reader :trips
|
41
|
+
private :trips
|
42
|
+
|
43
|
+
# @!attribute
|
44
|
+
# @return [Trip] the current hunting trip.
|
45
|
+
attr_reader :trip
|
46
|
+
private :trip
|
47
|
+
|
48
|
+
delegate [:contract, :traits, :arguments, :block] => :trip
|
49
|
+
|
50
|
+
# @!attribute contract
|
51
|
+
# @return [Class,Module,Symbol] contract being hunted for.
|
52
|
+
|
53
|
+
# @!attribute traits
|
54
|
+
# @return [Array<Symbol>] traits being hunted for.
|
55
|
+
|
56
|
+
# @!attribute [r] arguments
|
57
|
+
# @return [Array<Dependency>] dependency to pass to initializer of contract when found.
|
58
|
+
|
59
|
+
# @!attribute block
|
60
|
+
# @return [#call] block to pass to constructor of contract when found.
|
61
|
+
|
62
|
+
#
|
63
|
+
# @!endgroup Attributes
|
64
|
+
|
65
|
+
def initialize( scorpion, contract, traits, *arguments, &block )
|
66
|
+
@scorpion = scorpion
|
67
|
+
@trips = []
|
68
|
+
@trip = Trip.new contract, traits, arguments, block
|
69
|
+
end
|
70
|
+
|
71
|
+
# Hunt for additional dependency to satisfy the main hunt's contract and traits.
|
72
|
+
# @see Scorpion#hunt
|
73
|
+
def fetch( contract, *arguments, &block )
|
74
|
+
fetch_by_traits( contract, nil, *arguments, &block )
|
75
|
+
end
|
76
|
+
|
77
|
+
# Hunt for additional dependency to satisfy the main hunt's contract and traits.
|
78
|
+
# @see Scorpion#hunt
|
79
|
+
def fetch_by_traits( contract, traits, *arguments, &block )
|
80
|
+
push contract, traits, arguments, block
|
81
|
+
execute
|
82
|
+
ensure
|
83
|
+
pop
|
84
|
+
end
|
85
|
+
|
86
|
+
# Inject given `object` with its expected dependencies.
|
87
|
+
# @param [Scorpion::Object] object to be injected.
|
88
|
+
# @return [Scorpion::Object] the injected object.
|
89
|
+
def inject( object )
|
90
|
+
trip.object = object
|
91
|
+
object.injected_attributes.each do |attr|
|
92
|
+
next if object.send "#{ attr.name }?"
|
93
|
+
next if attr.lazy?
|
94
|
+
|
95
|
+
object.send :inject, attr, fetch_by_traits( attr.contract, attr.traits )
|
96
|
+
end
|
97
|
+
|
98
|
+
object
|
99
|
+
end
|
100
|
+
|
101
|
+
# Allow the hunt to spawn objects.
|
102
|
+
# @see Scorpion#spawn
|
103
|
+
def spawn( klass, *arguments, &block )
|
104
|
+
scorpion.spawn( self, klass, *arguments, &block )
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def execute
|
110
|
+
execute_from_trips || execute_from_scorpion
|
111
|
+
end
|
112
|
+
|
113
|
+
def execute_from_trips
|
114
|
+
return if arguments.any?
|
115
|
+
|
116
|
+
trips.each do |trip|
|
117
|
+
return trip.object if contract === trip.object
|
118
|
+
trip.arguments.each do |arg|
|
119
|
+
return arg if contract === arg
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def execute_from_scorpion
|
127
|
+
scorpion.execute self
|
128
|
+
end
|
129
|
+
|
130
|
+
def push( contract, traits, arguments, block )
|
131
|
+
trips.push trip
|
132
|
+
|
133
|
+
@trip = Trip.new contract, traits, arguments, block
|
134
|
+
end
|
135
|
+
|
136
|
+
def pop
|
137
|
+
@trip = trips.pop
|
138
|
+
end
|
139
|
+
|
140
|
+
class Trip
|
141
|
+
attr_reader :contract
|
142
|
+
attr_reader :traits
|
143
|
+
attr_reader :arguments
|
144
|
+
attr_reader :block
|
145
|
+
|
146
|
+
attr_accessor :object
|
147
|
+
|
148
|
+
def initialize( contract, traits, arguments, block )
|
149
|
+
@contract = contract
|
150
|
+
@traits = traits
|
151
|
+
@arguments = arguments
|
152
|
+
@block = block
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class InitializerTrip < Trip; end
|
157
|
+
end
|
158
|
+
end
|
data/lib/scorpion/hunter.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Scorpion
|
2
|
-
# A concrete implementation of a Scorpion used to hunt down food for a {Scorpion::
|
2
|
+
# A concrete implementation of a Scorpion used to hunt down food for a {Scorpion::Object}.
|
3
3
|
# @see Scorpion
|
4
4
|
class Hunter
|
5
5
|
include Scorpion
|
@@ -8,11 +8,11 @@ module Scorpion
|
|
8
8
|
# @!group Attributes
|
9
9
|
#
|
10
10
|
|
11
|
-
# @return [Scorpion::
|
12
|
-
attr_reader :
|
13
|
-
protected :
|
11
|
+
# @return [Scorpion::DependencyMap] map of {Dependency} and how to create instances.
|
12
|
+
attr_reader :dependency_map
|
13
|
+
protected :dependency_map
|
14
14
|
|
15
|
-
# @return [Scorpion] parent scorpion to deferr hunting to on missing
|
15
|
+
# @return [Scorpion] parent scorpion to deferr hunting to on missing dependency.
|
16
16
|
attr_reader :parent
|
17
17
|
private :parent
|
18
18
|
|
@@ -21,34 +21,35 @@ module Scorpion
|
|
21
21
|
|
22
22
|
def initialize( parent = nil, &block )
|
23
23
|
@parent = parent
|
24
|
-
@
|
24
|
+
@dependency_map = Scorpion::DependencyMap.new( self )
|
25
25
|
|
26
26
|
prepare &block if block_given?
|
27
27
|
end
|
28
28
|
|
29
29
|
# Prepare the scorpion for hunting.
|
30
|
-
# @see
|
30
|
+
# @see DependencyMap#chart
|
31
31
|
def prepare( &block )
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# @see Scorpion#hunt
|
36
|
-
def hunt_by_traits( contract, traits = nil, *args, &block )
|
37
|
-
unless prey = hunting_map.find( contract, traits )
|
38
|
-
return parent.hunt_by_traits contract, traits if parent
|
39
|
-
|
40
|
-
prey = Scorpion::Prey::ClassPrey.new( contract, nil ) if contract.is_a?( Class ) && traits.blank?
|
41
|
-
unsuccessful_hunt( contract, traits ) unless prey
|
42
|
-
end
|
43
|
-
prey.fetch self, *args, &block
|
32
|
+
dependency_map.chart &block
|
44
33
|
end
|
45
34
|
|
46
35
|
# @see Scorpion#replicate
|
47
36
|
def replicate
|
48
37
|
replica = self.class.new self
|
49
|
-
replica.
|
38
|
+
replica.dependency_map.replicate_from( dependency_map )
|
50
39
|
replica
|
51
40
|
end
|
52
41
|
|
42
|
+
# @see Scorpion#hunt
|
43
|
+
def execute( hunt )
|
44
|
+
dependency = dependency_map.find( hunt.contract, hunt.traits )
|
45
|
+
dependency ||= parent.dependency_map.find( hunt.contract, hunt.traits ) if parent
|
46
|
+
dependency ||= Dependency.define( hunt.contract ) if hunt.traits.blank?
|
47
|
+
|
48
|
+
unsuccessful_hunt( hunt.contract, hunt.traits ) unless dependency
|
49
|
+
|
50
|
+
dependency.fetch hunt
|
51
|
+
end
|
52
|
+
|
53
|
+
|
53
54
|
end
|
54
55
|
end
|
data/lib/scorpion/locale/en.yml
CHANGED
@@ -2,4 +2,8 @@ en:
|
|
2
2
|
scorpion:
|
3
3
|
errors:
|
4
4
|
messages:
|
5
|
-
unsuccessful_hunt: "Couldn't find a %{contract} builder with traits '%{traits}'"
|
5
|
+
unsuccessful_hunt: "Couldn't find a %{contract} builder with traits '%{traits}'"
|
6
|
+
builder_required: A custom builder must be provided to resolve this dependency
|
7
|
+
warnings:
|
8
|
+
messages:
|
9
|
+
mixed_scorpions: A scorpion has already been assigned. Mixing scorpions can result in unexpected results.
|