NemerleでDesign by contract
オンラインドキュメントを見てて、出来ることに気づいた。
using System; using Nemerle.Assertions; using Nemerle.IO; module Calc { [Requires(x >= 0 && y >= 0)] // 事前条件 [Ensures(value >= 0)] // 事後条件 public Add(x : int, y : int) : int { unchecked { x + y } } } module M { Main() : void { // 計算される printf("%d\n", Calc.Add(10, 20)); try { // x < 0なので事前条件に違反 printf("%d\n", Calc.Add(-1, 20)); } catch { | e : AssertionException => printf("%s\n", e.Message) } try { // y < 0なので事前条件に違反 printf("%d\n", Calc.Add(10, -1)); } catch { | e : AssertionException => printf("%s\n", e.Message) } try { // オーバーフローを起こす // value(メソッドの値、つまり戻り値) < 0なので事後条件に違反 printf("%d\n", Calc.Add(Int32.MaxValue, 1)); } catch { | e : AssertionException => printf("%s\n", e.Message) } } } /* 結果 30 assertion ``x >= 0 && y >= 0'' failed in file test.n, line 6: The ``Requires'' contract has been violated. assertion ``x >= 0 && y >= 0'' failed in file test.n, line 6: The ``Requires'' contract has been violated. assertion ``value >= 0'' failed in file test.n, line 7: The ``Ensures'' contract has been violated. */
こんな感じ。これもNemerleのマクロで実現されています。強力だなぁ。