I forget who made this point at RubyConf, but the best example of why
IoC and Copland are good things is the idea of a Black Box.

It's not generally good practice if you need to go back in and modify
code to simply reconfigure something. In a larger application, you
could conceivably need to have multiple configurations for multiple
environments that require different implementations of components. You
need to be able to treat a system as a black box; in this case, a
pluggable system with multiple compatible implementations of
subservices and dependencies. Modifying code for each deployment is
not scalable.

For example, what if some service was distributed as a gem file? You
would not want to be mucking about in the deployed gem contents to
reconfigure it, would you? Ideally, for any given use of that service,
you could have an appropriate configuration for your target
environment. You might want to log to a file on one system or two
Windows event logs on another. You might want to have a DBM-based
persistence mechanism or use something beefier backed by a large
ORDBMS. Making these changes shouldn't ever require modifying code.

The debate over whether YAML is the best way to handle this
configuration is a whole separate matter. Coming from a Java world,
YAML is a considerable improvement over the reams of XML descriptors
I'm used to, so I'm probably too biased to make a good
ruby-appropriate recommendation :)

- Charlie


On Wed, 6 Oct 2004 11:09:14 +0900, Jamis Buck <jgb3 / email.byu.edu> wrote:
> Paul Brannan wrote:
> > On Wed, Oct 06, 2004 at 05:25:40AM +0900, Richard Lyman wrote:
> >
> >>Say I wrote something that used 10 parts. I left it for a while, and
> >>later came back because I knew I could rewrite part #4 better. I
> >>wouldn't have to mess with parts 1-3, or parts 5-10. Just make sure
> >>part 4 quacks like the duck that it used to be and change a few lines
> >>in Copeland and you're in business.
> >
> >
> > What you are describing (duck typing) seems to me totally orthogonal to
> > Copland.  I can easily write my code like this:
> 
> Not exactly... Copland is actually based strongly on the fact that Ruby
> uses duck typing. It depends on that feature--thus, the two aren't
> really orthogonal. Although you can do duck typing without Copland, you
> can't do Copland without (at least some) duck typing. :)
> 
> >
> >   class Part1
> >     def initialize(part4)
> >       @part4 = part4
> >     end
> >   end
> >
> >   class Part4
> >   end
> >
> >   p4 = Part4.new
> >   p1 = Part1.new(p4)
> >
> > then come back later and change Part4 to something else and Part1 never
> > knows the difference.
> 
> Indeed, Paul -- you're using dependency injection here, without even
> knowing it. :) You're just doing manual dependency injection, without
> the benefit of any automation. For shallow dependency trees (typically
> only one or two levels deep), this works fine, and is going to be more
> efficient (though perhaps slightly less maintainable) than using a
> container like Copland. However, when you ramp the dependency tree to
> another level or two, or three, or four, it quickly becomes impossible
> to do manual dependency injection in any reasonable fashion. At that
> point, you'll either engineer your own solution, or take advantage of a
> package that does it for you (like Copland).
> 
> As an example, I started reworking Net::SSH to take advantage of
> Copland. I've only refactored a small fraction of it (maybe 10-15%), and
> I'm already dealing with dependencies 3 or 4 levels deep. The original
> implementation used either abstract factories, or just tightly coupled
> the components together (one big reason why Net::SSH lacks a decent
> suite of unit tests).
> 
> > Anyway, my point was that while Copland isn't particularly useful to me
> > (the bulk of the code I write is in C++, not Ruby), I'm nevertheless
> > interested in its development.
> 
> Glad to hear you haven't given up on it. :)
> 
> Thanks, Richard and Paul, for your feedback!
> 
> - Jamis
> 
> --
> Jamis Buck
> jgb3 / email.byu.edu
> http://www.jamisbuck.org/jamis
> 
>