<1> オブジェクト指向拡張と標準 Pascal のレコード型 (Pascal へのオブジェクト指向拡張の歴史と Delphi)

# 1. オブジェクト指向拡張と標準 Pascal のレコード型

当記事で書かれている **"オブジェクト指向拡張"** と **"Object Pascal"** の定義を先に述べておきます。そしてオブジェクト指向拡張と密接な関係にある Pascal のレコード型についても触れておきます。

## 1.1. オブジェクト指向拡張
初期は Borland、現在では Embarcadero が開発している **Delphi** が採用している言語はオブジェクト指向言語である **Object Pascal** です。

「何をもってオブジェクト指向言語なのか？」というのはとても難しい問いだとは思うのですが、**オブジェクト指向プログラミングの三原則**である `カプセル化`、 `継承`、 `多態性` が行える "クラスまたはその類似機能" を備えていれば "オブジェクト指向 (プログラミングが可能な) 言語" と言えると思います。

何をもって Object Pascal なのか？という問いに対しては、**Apple の Object Pascal** に沿った実装になっていれば Object Pascal と言えると思います。

途中で Borland が 「Delphi の言語は **Delphi 言語**」と言い出した事もありましたが「Pascal って古臭いイメージが付いて回ってるからとりあえず言語名から Pascal 抜いとこ」とかいう判断だったのだと思います、多分 [^1]。

## 1.2. 標準 Pascal のレコード型
Pascal には初期 [^3] から構造化型の一つとしてレコード型があります。

 - [<7> レコード型 (標準 Pascal 範囲内での Delphi 入門)](https://qiita.com/ht_deko/items/1d2c85768febc95009bf)
 - [<10> ポインタ型 (標準 Pascal 範囲内での Delphi 入門)](https://qiita.com/ht_deko/items/745ad4a792d277d33831)

詳細はリンク先の記事に譲るとして、簡単に言えば他言語で言うところの**構造体**です。Pascal のレコード型には**可変部**があり、可変部だけ見ると**共用体**でもあります。

複数の型を持つ要素を含められるため、クラスを実装するにはレコードを拡張するのが最も都合がよく、実際 Object Pascal のクラスはレコードを拡張した形で行われています。

### 1.2.1. (静的な) レコード

レコード型は型宣言部 (**type**) にて "型名 = **record** ～ **end;**" で定義します。変数宣言部 (**var**) でレコード型の変数を宣言すれば (静的な) レコードを使うことができます。

```pascal:RecordTest1.pas
program RecordTest1(Output);

type
  TRec = record { レコード型の定義 }
    ID: Integer;
    FirstName: packed array [1..20] of Char;
    LastName: packed array [1..20] of Char;
  end;  

var
  Rec: TRec; { レコード型変数の宣言 }

begin
  Rec.ID := 100;
  Rec.FirstName := 'Hello,              ';
  Rec.LastName  := 'world.              ';

  writeln(Rec.ID       );
  writeln(Rec.FirstName);
  writeln(Rec.LastName );
end.
```

上記例の場合、Rec は TRec 型の (静的な) 変数です。**標準 Pascal** の用語で詳細を説明すると次のようになります。

| 識別子 | 意味 |
|:--|:--|
| TRec | レコード型 |
| Rec | TRec 型の (静的な) 変数 |

 - 型定義部 (**type**) で TRec というレコード型が定義されている。
 - 変数宣言部 (**var**) で Rec という TRec レコード型が宣言されている。

ここでは後述する `動的な変数` の対比の意味で `(静的な) 変数` と呼んでいますが、**静的変数**と呼んでしまうと別の意味になってしまうので注意が必要です [^2]。

### 1.2.2. 動的なレコード
動的なレコードを使うには、定義したレコード型のポインタ型を定義し、New() で新しい動的レコード型変数を作成し、Dispose() で動的レコード型変数用に割り当てられたメモリを解放します。

```pascal:RecordTest2.pas
program RecordTest2(Output);

type
  TRec = record { レコード型の定義 }
    ID: Integer;
    FirstName: packed array [1..20] of Char;
    LastName: packed array [1..20] of Char;
  end;  
  PRec = ^TRec; { ポインタ型の定義 }

  
var
  Rec: PRec; { ポインタ型変数の宣言 }
  
begin
  New(Rec); { 動的変数用メモリの確保と識別値の割り当て }
  
  { 動的変数を逆参照してアクセス }
  Rec^.ID := 100; 
  Rec^.FirstName := 'Hello,              ';
  Rec^.LastName  := 'world.              ';

  writeln(Rec^.ID       );
  writeln(Rec^.FirstName);
  writeln(Rec^.LastName );

  Dispose(Rec); { 識別値が指す動的変数用メモリの解放 }
end.
```

上記例の場合、Rec は TRec 型のポインタ変数で、**Rec^** のようにキャレット記号 (^) を使って動的変数を逆参照しています。**標準 Pascal** の用語で詳細を説明すると次のようになります。

| 識別子 | 意味 |
|:--|:--|
| TRec | レコード型 (対象型) |
| PRec | ポインタ型 |
| Rec | ポインタ型変数 |
| Rec^ | TRec 型の動的変数 (対象変数) |

 - 型定義部 (**type**) で TRec というレコード型が定義されている。
 - 型定義部 (**type**) で TRec を**対象型**とするポインタ型 PRec が定義されている。
 - 変数宣言部 (**var**) で Rec という PRec ポインタ型が宣言されている。
 - New() で TRec 型の**動的変数 (対象変数)** 用メモリが確保され、動的変数を指し示す**識別値 (ポインタ値)** がポインタ型変数 Rec に格納される。
 - ポインタ型変数 Rec に格納されている**識別値 (ポインタ値)** から**動的変数 (対象変数)** を**逆参照**するには Rec^ のようにキャレット記号 (逆参照演算子) を使う。
 - Rec に格納されている**識別値 (ポインタ値)** が指し示す TRec 型の**動的変数 (対象変数)** が使っていたメモリは Dispose() で解放される。

Delphi では古いバージョンを除いて、逆参照演算子を省略できます [^4]。

# 参考文献

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/edb459ee-39a0-6313-69b1-7ec707394b11.png)

| タイトル | 著者 | ISBN-10<br>(Amazon) |出版年|
|:--|:--|:-:|:-:|
| PASCAL 原書第 4 版 | キャスリン・イェンゼン (著)<br>ニクラウス・ヴィルト (著)<br>アンドリュー・Ｂ・ミケル (編)<br>ジェームス・Ｆ・マイナー (編) <br>原田 賢一 (訳) |  [4563014664](https://www.amazon.co.jp/dp/4563014664/)  | 1993/10/30 |

標準 Pascal についてはこの本で大体理解できます。オススメ。

**See also:**

 - [『PASCAL』 - Wirth 先生の邦訳本を読んでみる (Qiita)](https://qiita.com/ht_deko/items/3086b7cff08928eca7a9#pascal-pascal)
 - [培風館の Pascal 関連書籍を読んでみる (Qiita)](https://qiita.com/ht_deko/items/65e84a12e0203da77337)
 - [標準 Pascal の規格票と解説書を読んでみる (Qiita)](https://qiita.com/ht_deko/items/091661d6fa3d72700a56)
 - [標準 Pascal 範囲内での Delphi 入門 (Qiita)](https://qiita.com/ht_deko/items/e2796788c65c2cda1de5)

# 索引
[ [↑ 目次へ](https://qiita.com/ht_deko/items/ff2d90c9174290583377) ] [ [→ 2. Clascal のオブジェクト指向拡張](https://qiita.com/ht_deko/items/770f2db98c9cf3e8ef7b) ]

<!-- 

[ [↑ 目次へ](https://qiita.com/ht_deko/items/ff2d90c9174290583377) ] [ [→ 2. Clascal のオブジェクト指向拡張](https://qiita.com/ht_deko/items/770f2db98c9cf3e8ef7b) ]

 -->

[^1]: Borland の中の人、あまり深く考えてなかったと思うよ。
[^2]: Delphi での静的変数については [標準 Pascal 範囲内での Delphi 入門 - (3.3.2.) 型付きの定数 (Typed Constants)](https://qiita.com/ht_deko/items/2d5996cbfc82d734b247#332-%E5%9E%8B%E4%BB%98%E3%81%8D%E3%81%AE%E5%AE%9A%E6%95%B0-typed-constants) を参照。
[^3]: Pascal は 1970 年に発表 (リリース) されています。
[^4]: Delphi 2 以降で(動的)レコード型の逆参照演算子が省略できます。