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