Class Dissident::Container
In: lib/nukumi2/vendor/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.

Methods

Attributes

cache  [RW]  The cache to keep track of instantiated objects.

Public Class methods

Define name to be a service that always returns value.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 293
293:       def constant(name, value)
294:         define_method name.to_sym do
295:           value
296:         end
297:       end

Define name to be the service returned by calling block.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 275
275:       def define(name, &block)
276:         define_method name, &block
277:       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

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 323
323:       def multimethod(name, *spec, &block)
324:         @@__dissident_mmd__ ||= {}
325:         (@@__dissident_mmd__[name] ||= []).unshift [spec, block]
326:         define_method name do |*args|
327:           _, mm = @@__dissident_mmd__[name].find { |(spec, block)|
328:             if spec.size == args.size
329:               spec.each_with_index { |s, i|
330:                 break false  unless s === args[i]
331:               }
332:             else
333:               false
334:             end
335:           }
336:           
337:           if mm.nil?
338:             raise NoMethodError,
339:             "undefined method `#{name}' for parameters #{args.inspect}"
340:           end
341:           mm.call(*args)
342:         end
343:       end

Define name to be the service that instantiates klass, optionally passing services as arguments to klass.new.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 282
282:       def provide(name, klass, *services)
283:         unless klass.kind_of? Class
284:           raise ArgumentError, "can only provide Classes"
285:         end
286:         
287:         define_method name.to_sym do |*args|
288:           klass.new(*(services.map { |service| container.fetch service } + args))
289:         end
290:       end

Public Instance methods

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

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 365
365:     def container
366:       cache or raise RuntimeError, "no container known."
367:     end

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 369
369:     def fetch(*args)
370:       container.fetch(*args)
371:     end

Return a prototype that will evaluate block on each instantiation.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 375
375:     def prototype(&block)
376:       if block.nil?
377:         raise ArgumentError, "prototype needs a block to evaluate each time"
378:       end
379:       Prototype.new(&block)
380:     end

[Validate]