

Contracts.ruby – Code contracts for Ruby - imd23
http://egonschiele.github.io/contracts.ruby/

======
egonschiele
Author here. Feel free to ask me any questions!

~~~
atmosx
What is the use case of 'contracts' exactly? From what I understand this is
not _standard ruby_ , it's something that comes from another language, right?

Why should I use contracts and not do something like: "var.is_a?
Float/String/etc." using exceptions to handle errors, which looks much more
elegant/rub-ish to me.

ps. I'm an developing ruby applications for fun mostly although I have
received a few ruby job offers. I am not an advanced ruby developer, so feel
free to verbose :-)

EDIT: Okay, maybe this can be used to enhance a testing framework?!

~~~
mhink
Depends on your definition of "standard Ruby". "Contract" is really just a
very clever method available in class scope on classes which use this library.
It's certainly inspired by method signature syntax in other languages, but at
its core, it's all implemented using metaprogramming facilities provided by
Ruby's "Module" and "Class" classes. It's a bit unorthodox, but it's also a
great example of how Ruby can be "molded" to be more expressive while still
being pretty much the same language.

As far as the use case is concerned: more or less, it's executable
documentation. In an expressive way, it both explains what to expect from the
method, and gives _useful_ error messages when those expectations are not met-
which saves you the trouble of figuring it out yourself.

One of the most annoying things in Ruby is trying to figure out why a
NoMethodError is getting thrown 40 frames down in the call stack, in code you
didn't personally write. Worse, a method just doesn't behave the way you'd
expect, and you're not sure why. Generally speaking, the unexpected behavior
is because the "implicit contract" of some method along the way changed, and
the methods around it weren't updated to handle the new return value. Boom,
now somewhere in your call stack you're getting a "NoMethodError: Undefined
method 'foobar' for nil:NilClass" and it's going to take 30 minutes of tracing
in pry to figure out where something's being called wrong.

As far as doing the same thing using "is_a?" and friends: you certainly could,
but that adds a lot of noise to your method body. When I'm looking at a
method, I want to cut through that noise and answer the question: "what does
this method actually do?" That said, I still want the benefits of validating
my arguments and return values. This gives me both.

------
rmchugh
this looks great! thanks egonschiele!

