On 4/30/07, Gary Wright <gwtmp01 / mac.com> wrote:
>
> On Apr 30, 2007, at 11:42 AM, Brian Guthrie wrote:
> > It's the sort of library that shouldn't necessarily be used in
> > production code anyway, though, due to the performance hit you take
> > from having to run each and every single method call through a filter.
>
> Makes sense.  Reminds me of Eiffel's ability to monitor pre/post
> conditions during development but to turn off those checks in
> production.
>
> One of the things that I thought was really nice about Eiffel's
> pre-condition checks was that any pre-condition exceptions were
> raised in the caller's context, which is conceptually where the
> error exists.  I think that would be difficult to do in Ruby without
> support in the runtime.
>
> Gary Wright
>

You can actually get a certain amount of the way there.  I'm currently
supporting a number of different checks:

 - invariants
 - pre/post conditions
 - method argument checks

There are a variety of different failure conditions for these.  If a
post-condition check fails then the blame lies with the method in
question.  If a precondition check fails then the caller is at fault.
Invariant checks are very difficult to pinpoint:  if an invariant
doesn't hold before a method is called it's very hard to figure out
why.

I'm currently doing my best to raise in the context of the method
around which the contract is placed but it's very difficult to raise
in the right place and to assign blame correctly.  Raising in the
context of the caller may be impossible without, as you suggest,
support in the runtime.  My understanding is that libraries exist for
deriving a useful call stack but I haven't explored them yet.

There's a gem if you're curious but the documentation isn't as good as
I'd like yet, and there are a few bugs.  You may also want to check
out Florian Gros ruby-contract.

Brian Guthrie