私が世界で最も愚かなリングバッファを持っているとしましょう。
size: constant := 16;
subtype T is integer;
package RingBuffer is
procedure Push(value: T);
function Pop return T;
end;
package body RingBuffer is
buffer: array(0..size) of T;
readptr: integer := 0;
writeptr: integer := 1;
procedure Push(value: T) begin
buffer(writeptr) := value;
writeptr := (writeptr + 1) mod size;
end;
function Pop return T
begin
readptr := (readptr + 1) mod size;
return buffer(readptr);
end;
end;
私のコードはひどいので、これを誤用しないように事前条件と事後条件を追加したいと思います。そこで、Push の実装を次のように変更します。
procedure Push(value: T) with
pre => readptr /= writeptr
is begin
buffer(writeptr) := value;
writeptr := (writeptr + 1) mod size;
end;
ただし、実装ではなく、プロシージャの宣言にアスペクト定義を配置する必要があるため、コンパイル エラーが発生します。
事は、これはパッケージです。私の宣言は公開されています。前提条件が依存している値は、宣言からは見えないパッケージ本体に属しています。アスペクト定義を宣言に入れるには、コードをリファクタリングして実装の詳細をパッケージの公開部分 (この場合はreadptr
とwriteptr
) に公開する必要があります。そして、私はそれをしたくありません。
私はこれを回避するいくつかの方法を考えることができます.callの実装を、実際に前提条件を持つ本体でのみ定義されPush()
たプライベートPushImpl()
プロシージャにするなどです...しかし、それは恐ろしいことです。これを行う正しい方法は何ですか?