there are at least two separate use cases I can think of;
1. there are certain dependencies that it was natural to access as global state - e.g. there is typically one stdout in a program and most code just prints to it 2. a class often hard codes constructors for its internal state, e.g. if you have a Graph class it would likely have associated Edge and Node classes that it calls internally to create new edges and nodes.
the big issue with both those is testing; if you want to mock the behaviour of the print statement, or you want a graph to hold nodes that track their own creation, or whatever, you have no way of overriding the internal constructors your class uses. hence dependency injection, the idea that e.g. a graph class would be defined with a node interface and you would pass it a concrete class when constructing it (some languages have type parameters for this, but even if they do you might not think to make something as simple as the node class used internally by the graph a type parameter, and more importantly you might want to set it at run time rather than compile time).
the issue was not that ruby didn't need dependency injection the concept, it's that it didn't need the sort of dependency injection frameworks that more rigid languages like java needed, you could use ruby's built in features to do the same thing.
> the idea that e.g. a graph class would be defined with a node interface and you would pass it a concrete class when constructing it
Right, but that's still just a generic instance of "plan ahead to use a parameter (possibly with a default value) instead of grabbing something hard-coded". I don't see a proposed fix for a class that was already designed to expect its own inner node implementation instead of an abstraction, except to rewrite it. Which is why it confused me, because the rewrite would just involve adding a parameter, so that you could pass an argument to it, and making the implementation use that parameter. I suppose in statically typed languages you might have to actually define an interface type for that parameter, whatever. None of that explained to me why the Java guys were talking about needing a "framework" to accomplish this, that apparently somehow involved a ton of XML.
> the issue was not that ruby didn't need dependency injection the concept, it's that it didn't need the sort of dependency injection frameworks that more rigid languages like java needed, you could use ruby's built in features to do the same thing.
Yes, it's much the same in Python. (And yes, I have for example used `print` as an argument to a higher-order function before.)