こんにちは。この講義では
Pharo の実行メカニズムや どのような種類のファイルが
いつどこで使われているのかを 見ていきましょう。
今までイメージファイルや ソースファイルや
チェンジファイルを使ってきました。
しかし、使ってはいましたが
それらがそれぞれ何をするのか 正確に説明しませんでした。
これを知ることで、間違えなしに きちんとシステムを操ることができます。
一言で言えば Pharo の実行メカニズムは
コンパイルされたコードを実行する 仮想機械（バーチャルマシン）です。
この仮想機械は プラットフォーム毎に用意されていて
MacOS や Windows や Linux や iOS や ARM や Android の
それぞれのバージョン用の VM があります。
C# や Java と同じ実行モデルです。
Pharo でも全く同じです。
多ステージコンパイルと呼ばれる方法を 使います。
プログラムをまず
プラットフォーム中立な命令である バイトコードにコンパイルし
仮想機械がバイトコードを アセンブリコードに変換します。
Pharo はこうして動いています。
他のオブジェクト指向言語も同様です。
仮想機械はファイルです。
OSによって .exe や .app になっていますが
それらが仮想機械です。
仮想機械は 2 つのモードで実行されます。
コマンドラインか、もしくは
GUI付きのインタラクティブモードです。
例えば、Linux サーバ上で Pharo を使う場合には
コマンドラインを使います。
仮想機械は コンパイルされたコードを実行して
同時にアセンブリを生成します。
このコンパイルされたコードは
イメージ中にパッケージされ 保存されます。
イメージはメモリのスナップショットで
Pharo の仮想的なオブジェクトシステムを 表しています。
これについては次回詳しく見ていきます。
仮想機械がプログラムを実行するために 必要なのはイメージだけです。
コードはイメージ中にコンパイルされ、また オブジェクトはイメージ中に存在するからです。
加えて、あと 3 つのファイルがあります。
イメージファイルとチェンジファイルと ソースファイルです。
これから、それぞれのファイルと その役割を説明していきます。
イメージファイルはオブジェクトを格納した メモリのスナップショットです。
Point や 文字列などのオブジェクトが 格納されています。
我々が使う、全てです。
さらに、コンパイル済みのメソッドや
コンパイル済みのクラスも 格納されています。
つまり、イメージを保存するたびに 全てのオブジェクトがディスクに保存されます。
イメージは本当に当時の時代の先を行く 仮想化システムです。
スタートアップ時には
保存されたオブジェクトが復元されます。
プログラムカウンタも
イメージに保存され
保存されたそのままに復元されます。
重要なことは OS と 仮想機械があり
仮想機械の上に
オブジェクトがいるメモリ空間である イメージがあり
イメージをディスクに保存し 復元できるということです。
そしてそのイメージにはコンパイル されたオブジェクトが詰まっています。
ここに 1 や 0 を書き込んだのは そういうことです。
さらに、チェンジファイルがあります。
チェンジファイルは、バックアップを 格納するファイルです。
Pharo 上で行った全てのことを記録し
ある種の巨大なテープのようなものに 書き込んでいきます。
そこには全てのコード追加や修正が 含まれています。
なんだか監視盗聴みたいな話ですが Pharo の内部的なことだけです。
これを使って、過去おこなった 一連の作業を再実行することもできます。
チェンジファイルは
Pharo への修正をおこなう全てのアクション を格納するバックアップテープなのです。
チェンジファイルはイメージファイルと 組みにして使います。
それはどうしてかというと
新しいクラスを定義すると
そのクラス定義は イメージファイルではなく
チェンジファイルに記録されます。
イメージファイルとチェンジファイルを バラバラにしてしまうと、コードを失います。
プログラムは実行し続けることができますが
ソースコードを失ってしまいます。
掘り下げて説明すると
イメージファイルにはバイトコードや
コンパイル済みのオブジェクトが バイナリ形式で格納されています。
それと平行して、チェンジファイルには 一連の修正が格納されています。
例えば、ここでカウンタに increase と decrease を追加しました。
他のクラスについても同様です。
そしてこれらの修正を再実行するための ツールが用意されています。
Pharo では、メソッドについて バージョンをブラウズすることができます。
このバージョンをブラウズするツールは チェンジファイルを使っています。
このペアを点線で囲っていますが
チェンジファイルとイメージファイルを 同期させることはとても重要です。
チェンジファイルの中身を emacs で編集したりしないでください。
やろうと思えばできるわけですが 良いことは何一つありません。
チェンジファイルを壊してしまうだけです。
イメージファイルは 一応はちゃんと動作し続けます。
チェンジファイルはプログラミング時に 必要なデータを見せるためのものなので。
しかし、やらないほうが良いです。
一般的に言って
イメージを使うと開発を身軽にできます。
何か作業をしている時に 誰かが割り込んできても
イメージを保存して ちょっと中断することができます。
作業に戻る時には 全く同じ状態から再開できます。
システムの状態の全てが ディスクに保存されるからです。
3 年後に作業を再開しても
ちゃんと 3 年前と全く同じ状態を 復元できます。
ただ、これは工学的な開発としては 良い実践習慣とは言えません。
プロトタイプ的な開発には良いですが。
工学的な開発では、かわりに バージョン管理システムを使ってください。
monticello という
Pharo で書かれた バージョン管理システムがあります。
Git バックエンドもあります。
コードをバージョン管理システムに保存して
Jenkins や Travis のような CI サーバを使って
作業開始ごとにイメージを構築しましょう。
Pharo を始める最初の時には これら 2 つのことを混同しがちです。
イメージは素早い開発には 極めて実践的な仕組みです。
しかし、より組織的で
大規模な統制的な開発では
古臭く見えてもそういったツールを 使うべきです。
実際に有用です。
プロトタイピングで 進める時期もありますが
いつかの時点で バージョン管理システムに保存して
環境から全てのバージョンに アクセスできるようにします。
例えば、Counter クラスを説明する 一連のビデオを参考にしてください。
3 つ目のファイルについてお話します。
ソースファイルです。
ソースファイルは ある種の特殊なチェンジファイルで
システムのリリース時の全ての定義を テキストとして格納しています。
Pharo の新しいバージョンごとに それぞれソースファイルがあり
このソースファイルには Array や Set 等の定義などの
Pharo のコアライブラリで定義された
全てのメソッドの定義が 格納されています。
一般にソースファイルは
リードオンリーで共有するのが良いです。
チェンジファイルは書き込み可で イメージごとに作られます。
これを見てください。
Pharo 4.0 いわば、この宇宙の
開始時の
システム状態のスナップショットです。
ここで新しいクラスを定義しました。 Node クラスを定義しました。
新しいオブジェクトのバイナリを 生成しました。
そのイメージと関連付けられた チェンジファイルには
新しい定義が追加されていきます。 ここに書かれています。
このファイルはリードオンリーです。
こちらは書き込みモードです。
もう一度言いますが 概念として
イメージファイルとチェンジファイルは 一緒になって機能を果たします。
これで 3 つのファイルの役割が 明確になったと思います。
理解しておくべきことは
チェンジについて管理するシステムで
さまざまなバージョンの復元や再実行を
簡単にできるようにしようとしています。
将来的には、Git との統合を改善して
実開発でのイメージ構築をするための 新しい手法を提案しようとしています。