> So, it's really a contractual thing, not so much a logic
> thing.
Exactly. The contract spells out the requirements that the client software
must adhere to and the results the server software will deliver.
> Doesn't that spread logic around anyway, though?
It does a bit. In Eiffel the pre and post conditions are syntactically part
of the method definition. And since pre/post conditions are inherited, you
only specify them at the parent level. You don't have to keep repeating
them in throughout the inheritance heirarchy.

Here's a twist on the original idea ... you could put them in the same file:

Class Person
def greet(other_person)
blah
end

precondition(:greet) do |other_person|
other_person.hand_condition != clammy
end

postcondition(:greet) do |result|
other_person.spouse == self && self.spouse == other_person
end
end

Here, the precondition/postcondition class methods can dynamically build the
:pre/:post methods and call the blocks, but only if
precondition/postcondition checking is enabled.

Aside: The contract in the above example is not the same as the examples in
previous messages. I delibrately changed it so there was an explicit
precondition. I figured the exact contract wasn't important to the course
of this discussion.
> I'm wondering what happens when the actual method needs a
> parameter to pass another test, does the programmer have to
> go open another file and assert the test there? It still
> feels like spreading logic around that really belongs in one
> place.
The contract is the formal spec of what you say you will do. The code is
where you do it. So there is some inherit duplication of information.

--
-- Jim Weirich / Compuware
-- FWP Capture Services
-- Phone: 859-386-8855