Class: DataProvider::Container
- Inherits:
-
Object
- Object
- DataProvider::Container
- Defined in:
- lib/data_provider/container.rb
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
- #add(container) ⇒ Object
-
#add!(container) ⇒ Object
adds all the providers defined in the given module to this class.
-
#add_scoped(container, _options = {}) ⇒ Object
adds all the providers defined in the given module to this class, but turns their identifiers into array and prefixes the array with the :scope option.
-
#add_scoped!(container, _options = {}) ⇒ Object
adds all the providers defined in the given module to this class, but turns their identifiers into array and prefixes the array with the :scope option.
-
#copy ⇒ Object
Data-related methods.
- #current_provider ⇒ Object
- #current_skip ⇒ Object
- #data ⇒ Object
- #fallback_provider ⇒ Object
- #fallback_provider? ⇒ Boolean
- #give(_data = {}) ⇒ Object (also: #add_scope, #add_data)
- #give!(_data = {}) ⇒ Object (also: #add_scope!, #add_data!)
- #given(param_name) ⇒ Object (also: #get_data)
- #got?(param_name) ⇒ Boolean (also: #has_data?)
- #has_provider?(identifier) ⇒ Boolean
- #has_providers_with_scope?(args) ⇒ Boolean
-
#initialize(_opts = {}) ⇒ Container
constructor
A new instance of Container.
- #logger ⇒ Object
- #missing_provider ⇒ Object
- #provider(identifier, opts = {}, &block) ⇒ Object
- #provider_id ⇒ Object
- #provider_identifiers ⇒ Object
- #provider_missing(&block) ⇒ Object
- #provider_stack ⇒ Object
- #providers ⇒ Object
-
#provides(_provides = nil) ⇒ Object
provides, when called with a hash param, will define ‘simple providers’ (providers with a simple, static value).
- #scope ⇒ Object
- #scoped_take(id) ⇒ Object
- #scopes ⇒ Object
- #take(id, opts = {}) ⇒ Object
-
#take_super(opts = {}) ⇒ Object
take_super is only meant to be called form inside a provider returns the result of next provider with the same ID.
- #try_take(id, opts = {}) ⇒ Object
Constructor Details
#initialize(_opts = {}) ⇒ Container
Returns a new instance of Container.
20 21 22 |
# File 'lib/data_provider/container.rb', line 20 def initialize _opts = {} = _opts.is_a?(Hash) ? _opts : {} end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
18 19 20 |
# File 'lib/data_provider/container.rb', line 18 def end |
Instance Method Details
#add(container) ⇒ Object
164 165 166 167 |
# File 'lib/data_provider/container.rb', line 164 def add(container) # make a copy and add the container to that give({}).add!(container) end |
#add!(container) ⇒ Object
adds all the providers defined in the given module to this class
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/data_provider/container.rb', line 145 def add!(container) ### add container's providers ### # internally providers are added in reverse order (last one first) # so at runtime you it's easy and fast to grab the latest provider # so when adding now, we have to reverse the providers to get them in the original order container.providers.reverse.each do |definition| add_provider(*definition) end ### add container's provides (simple providers) ### self.provides(container.provides) ### fallback provider ### @fallback_provider = container.fallback_provider.block if container.fallback_provider ### add container's data ### give!(container.data) end |
#add_scoped(container, _options = {}) ⇒ Object
adds all the providers defined in the given module to this class, but turns their identifiers into array and prefixes the array with the :scope option
193 194 195 |
# File 'lib/data_provider/container.rb', line 193 def add_scoped container, = {} copy.add_scoped!(container, ) end |
#add_scoped!(container, _options = {}) ⇒ Object
adds all the providers defined in the given module to this class, but turns their identifiers into array and prefixes the array with the :scope option
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/data_provider/container.rb', line 171 def add_scoped! container, = {} ### add container's providers ### container.providers.reverse.each do |definition| identifier = [definition[0]].flatten identifier = [[:scope]].flatten.compact + identifier if [:scope] add_provider(*([identifier]+definition[1..-1])) end ### add container's provides (simple providers) ### container.provides.each_pair do |key, value| provides(([[:scope]].flatten.compact + [key].flatten.compact) => value) end ### fallback provider ### @fallback_provider = container.fallback_provider.block if container.fallback_provider ### add container's data ### give!(container.data) end |
#copy ⇒ Object
Data-related methods
201 202 203 204 |
# File 'lib/data_provider/container.rb', line 201 def copy c = self.class.new c.add!(self) end |
#current_provider ⇒ Object
254 255 256 |
# File 'lib/data_provider/container.rb', line 254 def current_provider provider_stack.last end |
#current_skip ⇒ Object
270 271 272 |
# File 'lib/data_provider/container.rb', line 270 def current_skip (@skip_stack || []).last.to_i end |
#data ⇒ Object
206 207 208 |
# File 'lib/data_provider/container.rb', line 206 def data @data || {} end |
#fallback_provider ⇒ Object
65 66 67 68 |
# File 'lib/data_provider/container.rb', line 65 def fallback_provider block = @fallback_provider block.nil? ? nil : Provider.new(nil, nil, block) end |
#fallback_provider? ⇒ Boolean
70 71 72 |
# File 'lib/data_provider/container.rb', line 70 def fallback_provider? !fallback_provider.nil? end |
#give(_data = {}) ⇒ Object Also known as: add_scope, add_data
210 211 212 |
# File 'lib/data_provider/container.rb', line 210 def give(_data = {}) copy.give!(_data) end |
#give!(_data = {}) ⇒ Object Also known as: add_scope!, add_data!
217 218 219 220 221 |
# File 'lib/data_provider/container.rb', line 217 def give!(_data = {}) @data ||= {} @data.merge!(_data) return self end |
#given(param_name) ⇒ Object Also known as: get_data
226 227 228 229 230 231 |
# File 'lib/data_provider/container.rb', line 226 def given(param_name) return data[param_name] if got?(param_name) logger.debug "Data provider expected missing data with identifier: #{param_name.inspect}" # TODO: raise? return nil end |
#got?(param_name) ⇒ Boolean Also known as: has_data?
236 237 238 |
# File 'lib/data_provider/container.rb', line 236 def got?(param_name) data.has_key?(param_name) end |
#has_provider?(identifier) ⇒ Boolean
34 35 36 |
# File 'lib/data_provider/container.rb', line 34 def has_provider?(identifier) (provides.keys.find{|k| k == identifier} || get_provider(identifier)) != nil end |
#has_providers_with_scope?(args) ⇒ Boolean
38 39 40 41 |
# File 'lib/data_provider/container.rb', line 38 def has_providers_with_scope?(args) scope = args.is_a?(Array) ? args : [args] provider_identifiers.find{|id| id.is_a?(Array) && id.length > scope.length && id[0..(scope.length-1)] == scope} != nil end |
#logger ⇒ Object
24 25 26 27 28 |
# File 'lib/data_provider/container.rb', line 24 def logger @logger ||= [:logger] || Logger.new(STDOUT).tap do |lger| lger.level = Logger::WARN end end |
#missing_provider ⇒ Object
242 243 244 |
# File 'lib/data_provider/container.rb', line 242 def missing_provider @missing_provider end |
#provider(identifier, opts = {}, &block) ⇒ Object
30 31 32 |
# File 'lib/data_provider/container.rb', line 30 def provider identifier, opts = {}, &block add_provider(identifier, opts, block_given? ? block : nil) end |
#provider_id ⇒ Object
258 259 260 |
# File 'lib/data_provider/container.rb', line 258 def provider_id current_provider ? current_provider.id : nil end |
#provider_identifiers ⇒ Object
43 44 45 |
# File 'lib/data_provider/container.rb', line 43 def provider_identifiers (provides.keys + providers.map(&:first)).compact.uniq end |
#provider_missing(&block) ⇒ Object
60 61 62 63 |
# File 'lib/data_provider/container.rb', line 60 def provider_missing &block raise "DataProvider::Base#provider_missing expects a block as an argument" if !block_given? @fallback_provider = block end |
#provider_stack ⇒ Object
250 251 252 |
# File 'lib/data_provider/container.rb', line 250 def provider_stack (@stack || []).clone end |
#providers ⇒ Object
56 57 58 |
# File 'lib/data_provider/container.rb', line 56 def providers @providers || [] end |
#provides(_provides = nil) ⇒ Object
provides, when called with a hash param, will define ‘simple providers’ (providers with a simple, static value). When called without a param (or nil) it returns the current cumulative ‘simple providers’ hash
50 51 52 53 54 |
# File 'lib/data_provider/container.rb', line 50 def provides _provides = nil return @provides || {} if _provides.nil? add_provides _provides return self end |
#scope ⇒ Object
266 267 268 |
# File 'lib/data_provider/container.rb', line 266 def scope scopes.last || [] end |
#scoped_take(id) ⇒ Object
246 247 248 |
# File 'lib/data_provider/container.rb', line 246 def scoped_take(id) take(scope + [id].flatten) end |
#scopes ⇒ Object
262 263 264 |
# File 'lib/data_provider/container.rb', line 262 def scopes provider_stack.map{|provider| provider.id.is_a?(Array) ? provider.id[0..-2] : []} end |
#take(id, opts = {}) ⇒ Object
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 |
# File 'lib/data_provider/container.rb', line 74 def take(id, opts = {}) logger.debug "DataProvider::Container#take with id: #{id.inspect}" # first try the simple providers if provides.has_key?(id) && opts[:skip].nil? provider = provides[id] return provider.is_a?(Proc) ? provider.call : provider end # try to get a provider object provider = get_provider(id, :skip => opts[:skip]) if provider @stack = (@stack || []) + [provider] @skip_stack = (@skip_stack || []) + [opts[:skip].to_i] result = (opts[:scope] || self).instance_eval(&provider.block) @skip_stack.pop @stack.pop # execute provider object's block within the scope of self return result end # try to get a scoped provider object if scope.length > 0 scoped_id = [scope, id].flatten provider = get_provider(scoped_id, :skip => opts[:skip]) if provider @stack = (@stack || []) + [provider] @skip_stack = (@skip_stack || []) + [opts[:skip].to_i] result = (opts[:scope] || self).instance_eval(&provider.block) @skip_stack.pop @stack.pop # execute provider object's block within the scope of self return result end end # couldn't find requested provider, let's see if there's a fallback if provider = fallback_provider # temporarily set the @missing_provider instance variable, so the # fallback provider can use it through the missing_provider private method @missing_provider = id @stack = (@stack || []) + [provider] @skip_stack = (@skip_stack || []) + [opts[:skip].to_i] result = (opts[:scope] || self).instance_eval(&provider.block) # provider.block.call # with the block.call method the provider can't access private methods like missing_provider @skip_stack.pop @stack.pop # = nil @missing_provider = nil return result end # no fallback either? Time for an error raise ProviderMissingException.new(:provider_id => id) end |
#take_super(opts = {}) ⇒ Object
take_super is only meant to be called form inside a provider returns the result of next provider with the same ID
136 137 138 |
# File 'lib/data_provider/container.rb', line 136 def take_super(opts = {}) take(provider_id, opts.merge(:skip => current_skip + 1)) end |
#try_take(id, opts = {}) ⇒ Object
128 129 130 131 132 |
# File 'lib/data_provider/container.rb', line 128 def try_take(id, opts = {}) return take(id, opts) if self.has_provider?(id) || self.fallback_provider? logger.debug "Try for missing provider: #{id.inspect}" return nil end |