Class | Dissident::Container |
In: |
dissident.rb
|
Parent: | Object |
Dissident::Container is the superclass of all Dissident containers. It provides useful helpers for defining containers and implementing multi-method dispatch.
cache | [RW] | The cache to keep track of instantiated objects. |
Define name to be a service that always returns value.
# File dissident.rb, line 284 284: def constant(name, value) 285: define_method name.to_sym do 286: value 287: end 288: end
Define name to be the service returned by calling block.
# File dissident.rb, line 266 266: def define(name, &block) 267: define_method name, &block 268: end
Define name to be the service returned by calling block when the arguments of the service match against spec.
Arguments are matched with ===, for example:
multimethod :mmd, Object, Object do |a, b| [a, b] end multimethod :mmd, Integer do |a| 2 * a end multimethod :mmd, Integer, Integer do |a, b| a + b end multimethod :mmd, 2, 2 do |a, b| 22 end mmd(1, 2) #=> 3 mmd(3, 3) #=> 3 mmd(2, 2) #=> 22 mmd("foo", "bar") #=> ["foo", "bar"] mmd(22) #=> 44 mmd(1, 2, 3) #~> NoMethodError
# File dissident.rb, line 314 314: def multimethod(name, *spec, &block) 315: @@__dissident_mmd__ ||= {} 316: (@@__dissident_mmd__[name] ||= []).unshift [spec, block] 317: define_method name do |*args| 318: _, mm = @@__dissident_mmd__[name].find { |(spec, block)| 319: if spec.size == args.size 320: spec.each_with_index { |s, i| 321: break false unless s === args[i] 322: } 323: else 324: false 325: end 326: } 327: 328: if mm.nil? 329: raise NoMethodError, 330: "undefined method `#{name}' for parameters #{args.inspect}" 331: end 332: mm.call(*args) 333: end 334: end
Define name to be the service that instantiates klass, optionally passing services as arguments to klass.new.
# File dissident.rb, line 273 273: def provide(name, klass, *services) 274: unless klass.kind_of? Class 275: raise ArgumentError, "can only provide Classes" 276: end 277: 278: define_method name.to_sym do |*args| 279: klass.new *(services.map { |service| container.fetch service } + args) 280: end 281: end
Return the current cache used for keeping track of instantiated objects. You need to make use of this method when you need to instantiate services that need other services.
Example (better done using provide):
class MyContainer < Dissident::Container def service Service.new def def other_service # OtherService.new(service) # wrong! OtherService.new(container.service) # correct end end
# File dissident.rb, line 356 356: def container 357: @cache or raise RuntimeError, "no container known." 358: end