Why do type checks in dynamic code smell?

Because if you’re testing comprehensively, in my experience, you almost never need them. Unit and functional tests aren’t a panacea, but failures around incorrect types represent a miniscule proportion of the errors in the Ruby codebases I’ve worked on. You get them every once in a blue moon, but they are fixed easily and quickly, and everyone moves on with their lives. People still ask me sometimes if I miss static types, and my answer is always an unequivocal no. They eliminate a particular type of error that I almost never need to worry about.

Ola is also right that types aren’t the same as classes, and attempting to conflate the two will in all likelihood drive you towards class explosion and, ultimately, madness and penury.

That isn’t to say that interfaces shouldn’t have at least implicit contracts. In my own design, I try to follow the robustness principle whenever possible, and it improves code maintainability dramatically (nor does it does get discussed as a design principle nearly often enough). If it’s generally clear from reading the code what you can expect back from a method call and your types are suitably polymorphic then explicit type checks should be pretty rare.

HTML format spec runner now in Ioke/ISpec

Mansions of cards: Osinki, CDOs, and the role of software