OK.  So Ruby has enough dependency-injection/inversion-of-control
libraries as it is, but mine is quite different so I figured I¡Çd post
it.  It¡Çs about as simple as dependency-injection can possibly become
and there¡Çs no support for lifecycles, interception, or other framework
stuff.  Nor is there any support for parents, children, or other
relatives, so keep it to yourself.

Anyway, here¡Çs the code (as released under Ruby¡Çs license, so go ahead
and use it in whatever manner you see fit):

injector.rb:
------------

# contents: Dependency injection made simple.
#
# Copyright © 2005 Nikolai Weibull <nikolai / bitwi.se>

module Injector
  Dependencies = {}

  def needs(path)
    const_set path.sub(%r<.*/>, "").capitalize,
      if Dependencies.include? path
        Dependencies[path]
      else
        require path
        path.split(%r</>).inject(Object){ |o, e| o = o.const_get(e.capitalize) }
      end
  end

  def self.inject(deps)
    deps.each{ |path, value| Dependencies[path] = value }
  end
end

Yes, that¡Çs right!  All it does is make it easy to substitute the
definitions of classes.  But hey, that¡Çs precisely what I wanted (and
needed) for one of my projects.  And to be honest, I think that it¡Çs
enough under most circumstances.

An example of how to use it follows:

scanner.rb:
-----------

require 'injector'

class Scanner
  extend Injector
  needs 'error'

  def initialize(io)
    raise Error, "can only work with open io-ports" if io.closed?
    @io = io
  end

  ãë¥ç
end

error.rb:
---------

class Error < StandardError; end

driver.rb:
----------

require 'scanner'

class Driver
  ãë¥ç
end

tc_driver.rb:
--------------

require 'test/unit'
require 'injector'

require 'scanner'

class Error < ScriptError; end # Or something more creative, perhaps?

Injector.inject(
  'error' => Error
)

class TC_Driver < Test::Unit::TestCase
  ãë¥ç
end

So the idea is that under normal circumstances, ¡Æneeds¡Ç is just a
circumvention for not using ¡Ærequire¡Ç directly, but for trying times the
dependency can be changed to something more suitable.

I¡Çll probably make a real release of this soon, but I was looking for
some comments first, so please, indulge my interest,
        nikolai

-- 
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}