1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Delphi の例外処理〔裏〕

はじめに

先日『Delphi の例外処理』という記事を書きましたが、今回はその番外編となります。
Delphi の例外処理のパクリ元...じゃなかった、何からインスパイアされたのかを探る記事です。

元ネタ

Delphi の例外処理の元ネタは Ada だと思われます。

■ Ada の例外処理

例外処理を行うには Exceptions モジュールが必要です。

With Ada.Exceptions; Use Ada.Exceptions;

例外型の宣言

例外用の変数を用意する必要があります。

  EExcepton: exception;

raise 文

raise EExcepton with "Error Message";

with 以降は省略可能です。

例外文

大雑把に言えば

  begin
    -- 文リスト
  exception
    -- 例外ブロック
  end;

となります。例外ハンドラ

when [識別子 ":"] 例外型識別子 {"|" 例外型識別子} => 

となります。例外型識別子 の部分には others というキーワードを使う事もできます。具体的なコードは次のようになります。

test.adb
With Ada.Text_IO; Use Ada.Text_IO;  
With Ada.Integer_Text_IO; Use Ada.Integer_Text_IO;
With Ada.Exceptions; Use Ada.Exceptions;

procedure Program is
  EExceptonA, EExceptonB, EExceptonC, EExceptonD: exception;
begin
  -- 任意の処理
  begin
    raise EExceptonA with "Excepton Message"; -- ここを EExceptonB / C / D とかに変えてみてね
  exception
    when EExceptonA | EExceptonB =>
      Put_Line("Excepton A or B"); 
    when EExceptonC =>
      Put_Line("Excepton C");
    when E: others =>
      Put_Line(Exception_Message(E)); 
      raise;
   end;
end Program;

例外型を | (or) で結合できる事以外は Delphi の例外処理とよく似ていますね。

※ 上記コードは IDEONE で試す事ができます。

■ Turbo Modula-2 の例外処理

Modula-2 の言語仕様には例外処理が含まれていないのですが、Turbo Modula-2 1 には独自拡張として例外処理が追加されています。Ada の例外処理のサブセットみたいな感じです。

例外の宣言

例外はあらかじめメインブロックの外で宣言しておく必要があります。

例外宣言 = 
  "EXCEPTION" 識別子 {"," 識別子} .

Turbo PascalDelphi のラベル宣言のようなものです。

MODULE Program1;

EXCEPTION 
  EExceptonA, EExceptonB, EExceptonC, EExceptonD;

BEGIN

END Program1.

RAISE 文

RAISE EExceptonA , 'Excepton Message';

カンマ 以降は省略可能です。

例外文

Turbo Modula-2 の例外文は Turbo PascalDelphiInitialization セクションのようなもので、モジュールやルーチンの最後に例外ブロック (EXCEPTION セクション) が置かれます。Ada とは異なり、例外処理する領域としない領域を分ける事はできません。

例外ハンドラ = 
  "EXCEPTION" 例外 ["|" 例外 ]
  [ "ELSE" 文 ] .

ちょっと混乱しますが、Turbo Modula-2 では EXCEPTION セクションを例外ハンドラと呼ぶようです。

MODULE Program1;

EXCEPTION 
  EExceptonA, EExceptonB, EExceptonC, EExceptonD;

BEGIN

EXCEPTION
  * 例外ブロック *)
END Program1.

例外ブロックで処理されなかった例外は ELSE セクションで処理できます。

MODULE Program1;

EXCEPTION 
  EExceptonA, EExceptonB, EExceptonC, EExceptonD;

BEGIN

EXCEPTION
  * 例外ブロック *)
ELSE
  * 未処理例外 *)
END Program1.

例外ハンドラは次のようになります。

例外 = 
  識別子リスト ":" 文 .   

識別子リスト = 
  識別子 {"," 識別子} .

ちょっと混乱しますが、Turbo Modula-2 では例外ハンドラを例外と呼ぶようです。

Modula-2CASE 文によく似ており、カンマで区切って複数の例外を指定する事も出来ます。

Program1.mod
MODULE Program1;

EXCEPTION 
  EExceptonA, EExceptonB, EExceptonC, EExceptonD;

BEGIN
  RAISE EExceptonA , 'Excepton Message';
EXCEPTION
  EExceptonA, EExceptonB:
    WRITELN('Excepton A or B')|
  EExceptonC:
    WRITELN('Excepton C');
ELSE
  WRITELN('Excepton Others');
END Program1.

CP/M-80 版の Turbo Modula-2 にもちゃんと例外処理が実装されています。
image.png
恐るべし、Borland!

おわりに

Delphi の例外型はクラスなので、派生によってグループ化ができます。このため「例外を Ada のようにor 結合 したり Turbo Modula-2 のように カンマ区切り できなくとも問題はない」といった判断だったのかもしれませんね。

See also:


  1. PIM3 準拠。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?