Download - 僕と契約プログラミングしようよ
![Page 1: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/1.jpg)
僕と契約プログラミングしようよ
七瀬 (@nanasetomona)
kstm LT #02015/04/09
![Page 2: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/2.jpg)
自己紹介
•七瀬
•長野県出身
• M2 – MMS研究室
![Page 3: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/3.jpg)
@nanasetomona
https://github.com/nanase
![Page 4: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/4.jpg)
![Page 5: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/5.jpg)
![Page 6: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/6.jpg)
![Page 7: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/7.jpg)
Assertion failed?
![Page 8: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/8.jpg)
契約プログラミング
•コード中に満たすべき仕様、条件を記述
▫実際のコードと仕様がセット
▫検証コード = 仕様
![Page 9: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/9.jpg)
2つのエラー
int main(void) {
double value = divide(2.0, 0.0);
return 0;
}
double divide(double a,
double b) {
return a / b;
}
![Page 10: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/10.jpg)
2つのエラー
int main(void) {
double value = divide(2.0, 0.0);
return 0;
}
double divide(double a,
double b) {
return a / b;
}
引数をNaNにしたらvalueもNaNになってしま
う!
不正な値になるのは仕様?バグ?
![Page 11: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/11.jpg)
エラーの切り分け
•エラー発生は
▫利用方法が間違っているから
▫実装が間違っているから
![Page 12: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/12.jpg)
事前条件
•機能の利用者が守るべき仕様を書く
▫ 引数の数
▫ 引数の型
▫ 引数の値の範囲
▫ 引数の値の状態
![Page 13: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/13.jpg)
事後条件
•機能の実装者が守るべき仕様を書く
▫ 返却値の数
▫ 返却値の型
▫ 返却値の値の範囲
▫ 返却値の値の状態
(不変条件(invariant) については省略)
![Page 14: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/14.jpg)
事前条件 (D言語の場合)
double divide(double a, double b)
in {
assert(!isNaN(a) && !isNaN(b));
assert(isFinite(a) || isFinite(b));
}
body {
return a / b;
}a も b も NaNでない
かつa も b も有限の値
![Page 15: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/15.jpg)
事後条件 (D言語の場合)
double divide(double a, double b)
in {
assert(!isNaN(a) && !isNaN(b));
assert(isFinite(a) || isFinite(b));
}
out(res) {
assert(!isNaN(res));
}
body {
return a / b;
}
返却値resはNaNではない
![Page 16: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/16.jpg)
アサーション
• assertion (表明、主張、断言)
▫ 満たすべき条件を表明する
▫ 常に真とならなければいけない条件を表明する
▫ 様々な言語でサポート(D言語では言語レベルでサポート)
assert(value == 0);
![Page 17: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/17.jpg)
エラーは無くなりません
• 契約はエラーを直接減らすものではない
▫ あくまでエラー原因を探求するためのもの
• 単体テスト・結合テストなど
▫ D言語はunittestキーワードがあります
▫ ここでもアサーションを使用
![Page 18: 僕と契約プログラミングしようよ](https://reader034.vdocuments.pub/reader034/viewer/2022042817/55a77b1b1a28ab3e4e8b46f3/html5/thumbnails/18.jpg)
出典
• Simutransロゴ:Artistic License 2.0 - http://www.simutrans.com/en/resources