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.

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 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.

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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

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 dissident.rb, line 356
356:     def container
357:       @cache or raise RuntimeError, "no container known."
358:     end

[Source]

     # File dissident.rb, line 360
360:     def fetch(*args)
361:       container.fetch(*args)
362:     end

Return a prototype that will evaluate block on each instantiation.

[Source]

     # File dissident.rb, line 366
366:     def prototype(&block)
367:       if block.nil?
368:         raise ArgumentError, "prototype needs a block to evaluate each time"
369:       end
370:       Prototype.new &block
371:     end

[Validate]