> So the code containing this typo was never tested?
The code absolutely was tested. However, (obviously) not every possible path through the code was tested.
Given a long-enough timeline, you will NEVER remember to test every little thing. Given sufficient code complexity, it can be next to impossible to actually exercise every code path with hand-written tests.
That's one of the troubles with large projects written scripting languages like Ruby... you have to write an assload of tests to replace what you get for free in languages (even "loosely"-typed languages like Erlang) that have pre-runtime type-checking (whether or not it's provided by a compiler).
> Conversely, I often work on projects which are neither large nor long-running - for those, a dynamically-typed scripting language works perfectly well.
Oh yeah, for small things such languages are A-OK. I 1000% agree with that. The big problem (that you may never encounter because I bet that you're smarter than the average unending parade of Project Managers) is how often small projects are forced into becoming big projects, and then huge projects as time goes on.