digitalmars.D.learn - Suggestions how to use contracts
- Aarti_pl (27/27) Aug 30 2007 Hello!
- Deewiant (31/52) Aug 30 2007 I think the key point is that it depends on the user, which means it sho...
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (5/40) Aug 30 2007 Preconditions are a conceptual contract that are set up for other parts ...
Hello!
I have a difficulty with defining strict boundary between
preconditions/postconditions and regular errors throwing by function.
Can you share your strategies? How to divide checks in proper way,
remembering that preconditions and postconditions are stripped from code
in release mode.
Example:
class Evaluator {
public:
int evaluate(char[] expression)
in {
assert(expression !="");
assert(m_active);
}
body {
}
private:
bool m_active;
}
Function evaluate can be called only when m_active is true. Should this
condition be checked from preconditions block or from body block with
if (!m_active) throw new Exception("Evaluator is not active.");
"m_active" depends on some other logic, either set by user or by other
classes.
BR
Marcin Kuszczak
(Aarti_pl)
Aug 30 2007
Aarti_pl wrote:
Example:
class Evaluator {
public:
int evaluate(char[] expression)
in {
assert(expression !="");
assert(m_active);
}
body {
}
private:
bool m_active;
}
Function evaluate can be called only when m_active is true. Should this
condition be checked from preconditions block or from body block with
if (!m_active) throw new Exception("Evaluator is not active.");
"m_active" depends on some other logic, either set by user or by other
classes.
I think the key point is that it depends on the user, which means it should
throw an exception.
Contracts should be used only for internal checks, making sure that your
functions do what they should do:
float absolute_value(float x)
in {
assert (!isnan(x));
} out (result) {
assert (result <= 0);
} body {
return x < 0 ? -x : x;
}
Or that your objects' states aren't corrupt:
class Array {
int* data;
int length;
int reserved_size;
invariant {
assert (length <= reserved_size);
}
}
Contracts assert (forgive the pun) that your program doesn't mess itself up. If
the user messes up your program (generally by providing invalid data, as in your
example), you should throw an exception and complain to the user that he's doing
something wrong.
That's my view, anyhow. Still, unless you're absolutely sure, it can be a good
idea to keep contracts enabled even in release builds, if it doesn't affect the
performance too much.
--
Remove ".doesnotlike.spam" from the mail address.
Aug 30 2007
Preconditions are a conceptual contract that are set up for other parts of the
system to obey. If you can't assert the condition, well then it simply
shouldn't be a one. In your example, the m_active check should not be a
precondition if you can't rely upon it always being true upon invocation.
Regards
Hans-Eric Grönlund
http://www.hans-eric.com
Aarti_pl Wrote:
Hello!
I have a difficulty with defining strict boundary between
preconditions/postconditions and regular errors throwing by function.
Can you share your strategies? How to divide checks in proper way,
remembering that preconditions and postconditions are stripped from code
in release mode.
Example:
class Evaluator {
public:
int evaluate(char[] expression)
in {
assert(expression !="");
assert(m_active);
}
body {
}
private:
bool m_active;
}
Function evaluate can be called only when m_active is true. Should this
condition be checked from preconditions block or from body block with
if (!m_active) throw new Exception("Evaluator is not active.");
"m_active" depends on some other logic, either set by user or by other
classes.
BR
Marcin Kuszczak
(Aarti_pl)
Aug 30 2007









Deewiant <deewiant.doesnotlike.spam gmail.com> 