関数に入るとき, 関数から出るとき, あるいはクラスの特定の状態において, 絶対に成立していなければならない条件をプログラムに記述することで, バグの発見 を容易にすることができる.
なお, -release オプションをつけてコンパイルすればテストコードを含まないバイナリ を生成する.
inout.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import std.stdio;
import std.math;
double squareRoot(double x){
in{
assert (x >= 0);
}
out(result){
assert( (result * result) == x);
}
body{
return sqrt(x);
}
}
void main(){
writeln( squareRoot(100) );
// writeln( squareRoot(-100) ); // AssertError InException
// writeln( squareRoot(5) ); // AssertError OutException
}
|
事前条件 in, body 節に入る直前に実行される.
事後条件 out, body 節から出る直前に実行される.
契約は interface にも書くことができる. その際は body 節はない:
interface I{
int foo(int n)
in{
assert(n > 0);
}
out(result){
assert(result < 100);
}
}
import std.stdio;
class Date{
uint month;
uint day;
this(){
month = 1;
day = 1;
}
void setDate(uint m, uint d){
month = m;
day = d;
}
invariant{
assert(1 <= month && month <= 12);
assert(1 <= day && day <= 31);
}
}
void main(){
Date date = new Date;
date.setDate(10, 7);
// date.setDate(13, 7); // AssertError
}
不変条件 invariant, コンストラクタ完了直後, デストラクタ実行直前, public/export メンバ関数の実行前後にチェックされる.