Ruby is dynamically and strong typed programming language. In the most of the cases it gives you required level of type safety with minimal code. But if you want build more secure applications or you’re like static typing, then you need to check every variable or method for it’s type or class:
But what if you’re needing more complex type checking on multiple types or conditions? Then you need to provide more boilerplate, defensive code. If you’re want to make your type safety code much cleaner, there is the contracts library.
What is a contract? It’s a pattern, that comes from functional programming world. In most cases this is one line of code before function or method, that validates the arguments and validates return value.
For example, there is a simple contract:
You can also use it on multiple arguments or returns:
If you don’t want to throw exception, you can easily override error callback:
Contracts library comes with many built-in type contracts:
- Basic types:
Num, Pos, Neg, Nat, Bool, Any, None
Maybe, Or, Xor, And, Not
ArrayOf, SetOf, HashOf, RangeOf, Enum
and others. But if your want to create your own types or check more complex conditions, then you have to use lambdas:
Pattern matching, like a contract, comes from functional programming. You can use your contracts to test if your method matches pattern or not. For example, let’s find a factorial of number with contracts:
Ruby has simple and powerful type system, but if it’s not enough or you want to use safety type checking and you don’t like to write tons of a defensive code, then you may like Contracts library. Contracts allows you to check many types, conditions for your class methods much cleaner and simpler. Also you can define your own types or conditions with plain Ruby lambdas, and then use them for pattern-matching.
If you’re like it and want to know more, there is Ruby contracts tutorial.