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
- #default_priority ⇒ 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
168 169 170 171 |
# File 'lib/data_provider/container.rb', line 168 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
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/data_provider/container.rb', line 149 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
197 198 199 |
# File 'lib/data_provider/container.rb', line 197 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
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/data_provider/container.rb', line 175 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
205 206 207 208 |
# File 'lib/data_provider/container.rb', line 205 def copy c = self.class.new c.add!(self) end |
#current_provider ⇒ Object
258 259 260 |
# File 'lib/data_provider/container.rb', line 258 def current_provider provider_stack.last end |
#current_skip ⇒ Object
274 275 276 |
# File 'lib/data_provider/container.rb', line 274 def current_skip (@skip_stack || []).last.to_i end |
#data ⇒ Object
210 211 212 |
# File 'lib/data_provider/container.rb', line 210 def data @data || {} end |
#default_priority ⇒ Object
30 31 32 |
# File 'lib/data_provider/container.rb', line 30 def default_priority [:default_priority].to_i end |
#fallback_provider ⇒ Object
69 70 71 72 |
# File 'lib/data_provider/container.rb', line 69 def fallback_provider block = @fallback_provider block.nil? ? nil : Provider.new(nil, nil, block) end |
#fallback_provider? ⇒ Boolean
74 75 76 |
# File 'lib/data_provider/container.rb', line 74 def fallback_provider? !fallback_provider.nil? end |
#give(_data = {}) ⇒ Object Also known as: add_scope, add_data
214 215 216 |
# File 'lib/data_provider/container.rb', line 214 def give(_data = {}) copy.give!(_data) end |
#give!(_data = {}) ⇒ Object Also known as: add_scope!, add_data!
221 222 223 224 225 |
# File 'lib/data_provider/container.rb', line 221 def give!(_data = {}) @data ||= {} @data.merge!(_data) return self end |
#given(param_name) ⇒ Object Also known as: get_data
230 231 232 233 234 235 |
# File 'lib/data_provider/container.rb', line 230 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?
240 241 242 |
# File 'lib/data_provider/container.rb', line 240 def got?(param_name) data.has_key?(param_name) end |
#has_provider?(identifier) ⇒ Boolean
38 39 40 |
# File 'lib/data_provider/container.rb', line 38 def has_provider?(identifier) (provides.keys.find{|k| k == identifier} || get_provider(identifier)) != nil end |
#has_providers_with_scope?(args) ⇒ Boolean
42 43 44 45 |
# File 'lib/data_provider/container.rb', line 42 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
246 247 248 |
# File 'lib/data_provider/container.rb', line 246 def missing_provider @missing_provider end |
#provider(identifier, opts = {}, &block) ⇒ Object
34 35 36 |
# File 'lib/data_provider/container.rb', line 34 def provider identifier, opts = {}, &block add_provider(identifier, opts, block_given? ? block : nil) end |
#provider_id ⇒ Object
262 263 264 |
# File 'lib/data_provider/container.rb', line 262 def provider_id current_provider ? current_provider.id : nil end |
#provider_identifiers ⇒ Object
47 48 49 |
# File 'lib/data_provider/container.rb', line 47 def provider_identifiers (provides.keys + providers.map(&:first)).compact.uniq end |
#provider_missing(&block) ⇒ Object
64 65 66 67 |
# File 'lib/data_provider/container.rb', line 64 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
254 255 256 |
# File 'lib/data_provider/container.rb', line 254 def provider_stack (@stack || []).clone end |
#providers ⇒ Object
60 61 62 |
# File 'lib/data_provider/container.rb', line 60 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
54 55 56 57 58 |
# File 'lib/data_provider/container.rb', line 54 def provides _provides = nil return @provides || {} if _provides.nil? add_provides _provides return self end |
#scope ⇒ Object
270 271 272 |
# File 'lib/data_provider/container.rb', line 270 def scope scopes.last || [] end |
#scoped_take(id) ⇒ Object
250 251 252 |
# File 'lib/data_provider/container.rb', line 250 def scoped_take(id) take(scope + [id].flatten) end |
#scopes ⇒ Object
266 267 268 |
# File 'lib/data_provider/container.rb', line 266 def scopes provider_stack.map{|provider| provider.id.is_a?(Array) ? provider.id[0..-2] : []} end |
#take(id, opts = {}) ⇒ Object
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 |
# File 'lib/data_provider/container.rb', line 78 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
140 141 142 |
# File 'lib/data_provider/container.rb', line 140 def take_super(opts = {}) take(provider_id, opts.merge(:skip => current_skip + 1)) end |
#try_take(id, opts = {}) ⇒ Object
132 133 134 135 136 |
# File 'lib/data_provider/container.rb', line 132 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 |