2018年7月13日

スクリプトライクに GNU Smalltalk を扱う試み #1: 単純なビルド環境の構築

Smalltalk は自分にとって最も好きなプログラミング言語だ。今現在ではまるで珍しい考え方ではない OOPMVC をはじめとしたデザインパターン)を始めクロージャやそれに基づく DSL の考え方等を 1980 年代に既に実装していた恐るべき先見性をもったプログラミング言語である。

趣味で使うなら Smalltalk を使いたい。特に Python のように「手軽なスプリクトライク」で使いたい。だが Smalltalk 環境(代表的なもので Squeak 及びその派生である Pharo 等)はその独自性故に、プログラミングするとなると大袈裟になりすぎるきらいがある。

Smalltalk 環境のひとつである GNU Smalltalk は CUI 上で実行出来る手軽さがあり、これを利用して Python ライクなスクリプティング環境を構築出来ないだろうか試してみよう、と思いたった。

GNU Smalltalk
GNU Smalltalk User's Guide: GNU Operating System
GNU Smalltalk: Wikipedia

・GNU Smalltalk の実行環境

例えば「C言語」ならビルドはハードウェアの環境で静的に完結するもので、ビルドした時点でその環境で実行可能な「実行ファイル」がビルドされる。こうしてビルドされた実行ファイルを実行すればそのプログラムが実行される。

Smalltalk は仮想マシン上で動作する言語であり、仮想マシン上で動作するイメージファイルに実行される環境の全てが定義される(これは Smalltalk の独自的な長所であると同時に、理解しづらい特性でもある)。このイメージに定義を追加することでイメージが拡張され、その拡張されたイメージが事実上実行ファイルの役割を果たす。

例えば、コマンドライン上で GNU Smalltalk を実行するとして

$ gst -q
GNU Smalltalk ready
(システムデフォルトのイメージで GNU Smalltalk を実行)

st> Object subclass: #You
( You クラスを定義する)

st> You class extend [ say [ 'Yes'  displayNl ] ]
( Yes と答える You クラスの say クラスメソッドを定義)

st> You say
Yes
( say クラスメソッドを呼び出すと Yes と答える)

st > ObjectMemory snapshot: 'SayYes.im'
(現在のイメージをスナップショットとして保存)

st> ^C
(Ctrl+c でプロセスを終了)

$ gst -q
GNU Smalltalk ready
(再びシステムデフォルトのイメージで GNU Smalltalk を実行)

st> You isNil displayNl
true
(システムデフォルトのイメージで You クラスは定義されていない)

st> ^C
(Ctrl+c でプロセスを終了)

$ gst -qI SayYes.im
GNU Smalltalk ready
(先ほどスナップショットした SayYes.im イメージで GNU Smalltalk を実行)

st> You say
Yes
( スナップショットとして保存した SayYes.im では You クラスが定義されており say クラスメソッドを呼び出すと Yes と答える)

このように、仮想マシンに対するイメージファイルの定義を拡張することで「実行ファイル」に相当する実行環境の拡張が出来る。

・GNU Smalltalk のソースファイル

GNU Smalltalk におけるソースファイルは .st 拡張子で保存できる。コマンドラインで一行ずつ入力しなくても、このようなソースファイルがあればファイル単位での読み込みが可能。ここでは HelloWorld.st を作成し、次のような Hello World コードを書き込む(下記のパッケージの例で使用する)。

Object subclass: World [
    World class >> sayToMe [ 'Hello!' displayNl ]
]

・GNU Smalltalk のパッケージ管理

GNU Smalltalk User's Guide: 3 Packages

gst-package コマンド

GNU Smalltalk はソースファイルの集合をパッケージとして定義し、指定したイメージファイルに一律に適用(ロード)する事が出来る。これには gst-package コマンドを使う。このコマンドは package.xml(フォーマットは上記リンク参照)の XML ファイルで定義されている .st 拡張子のソースファイルを一律にパッケージング及びインストールする機能を持つ。

下記のコマンドはカレントディレクトリに package.xml に基づいた .star パッケージを作成する。このパッケージは配布可能であり、受け取った人は自身の GNU Smalltalk システムにインストール可能。

$ gst-package -t. package.xml

下記のコマンドは実行中のユーザのディレクトリ下(~/.st)に package.xml で定義した .star パッケージを作成してインストールする。

$ gst-package -t ~/.st package.xml

パッケージを直接指定してインストールすることもできる。

$ gst-package -t ~/.st パッケージ名.star

gst-load コマンド

例えば package.xml において

<package>
     <name>HelloWorld</name>
     <file>HelloWorld.st</file>
     <filein>HelloWorld.st</filein>
</package>

と定義されて HelloWorld パッケージとされ、上記の gst-package コマンドによって ~/.st にインストールされていたとする。

パッケージをインストールしたユーザは gst-load コマンドによって任意のイメージにインストールした HelloWorld パッケージ(ソースとしては HelloWorld.st のみ)をロード出来る。 ~/.st ディレクトリは GNU Smalltalk がパッケージの取得のために参照するユーザディレクトリであり、ここにある .star パッケージは実行中のユーザがロード可能になる。

あらかじめシステムにインストールされているコアライブラリ( SQL データベースやネットワークソケットライブラリ等)も gst-load でロード出来る。

$ gst-load HelloWorld -I SayYes.im
( SayYes.im イメージに HelloWorld.st を含む HelloWorld パッケージを適用)

$ gst -qI SayYes.im
GNU Smalltalk ready
(パッケージを適用した SayYes.im を読み込む)

st> World sayToMe
Hello!
( HelloWorld.st で定義されている World クラスがロードされている)

・ここまでの知識を活かしてテキストエディタを扱う

Atom 等のプログラミング用のテキストエディタ上でも、上記の gst-package や gst-load を用いればシェルスクリプト等で簡易的なビルドスクリプト(的なもの)を組む事は容易い。こんな感じで GNU Smalltalk を活用すれば、 Python のようにスクリプトライクに GNU Smalltalk を扱うことが出来る、かもしれない。

なお、作ったスクリプトは GitHub にアップロードしてある

シェルスクリプトによる簡易的な GNU Smalltalk のビルドスクリプト的なもの

0 件のコメント:

コメントを投稿