Adding type constraint checks to dynamic languages is not "horrifying". It's merely using the language to extend the language; where you want type checks, you can have type checks.
So for example to see if some object is iterable, you just check if it responds to each.
obj.responds_to?(:each)