I don't know a great deal about ruby, but I'd wager that the way it's designed would make static type checking essentially impossible. And you probably understand this, but still. Dynamic languages allow fundamentally unsound types, for example:
def foo(x):
print x
return foo
This function has no computable type (in a standard system anyway); it's "a -> a -> a -> ...". However it's perfectly obvious what it does, and conceivable that it or similar functions might exist and be useful in actual code. Dynamic languages allow behaviors which are impossible in statically typed languages (properties created at runtime are another example).
Of course, one could use gradual typing to get around some of this.
In the same way that writing a unit test for something proves your logic is correct? This is not intended as a snark or something. Just stating the obvious that your unit tests are no silver bullet to a working correct piece of software.
My 2 cents: Combine static(ish) typing with tests and a number of (semi-manual) test scenario's and you get a few steps closer to a correctly working piece of software.
Manual testing is what really confirms that your code is working properly. Automated testing verifies the conditions necessary for your code to pass manual testing. The real value of automated tests is for when you need (or someone else needs) to come back and change something.
I don't think static typing is necessary in that case, but I understand it has benefits in some situations.
How about static compiler checks? :)