はじめに
Smalltalkの魅力の1つはライブプログラミングにあります。ライブプログラミングとは、プログラムを動かしながらそのプログラムを変更し、その変更を反映させながらプログラムがそのまま継続実行されることを指します。
ライブプログラミングはよく活線配線に例えられます。そう、電源に繋がっていて、スイッチが入っていて、回路に電圧がかかり電流が走りまくっている中で電線を切ったりワイヤを繋げたりするようなものです。この危険と背中合わせなスリリングなプログラミングこそがSmalltalkの華といえます。ヒャッハー!
一方で、昔、あるSmalltalkerから「自分自身を壊せないような言語はだめだ」みたいなことを言われたことがあります。いやー、安全なほうがいいでしょう、とは思うのですが、一方で自爆スイッチの魅力には抗い難いものがあります。そう、Smalltalkはそのシンプルさと強力さの裏返しで、活線状態の魅力的な自爆スイッチがいっぱいあるのです。
壊す方法を知ることは、壊さないようにする方法を知ることに繋がります。さあ、みんなで安全なSmalltalkプログラミングのために、自爆スイッチを押してみましょう。今回はPharo 5で試してみました。
Smalltalkの無の境地
SmalltalkにはSmalltalk
というグローバル変数があります。こいつはクラスを含む全てのグローバル変数を管理するとともに、Pharoなどの実装ではオブジェクトメモリの管理やスタートアップ・シャットダウンの処理などを行う大事なオブジェクトです。にやり。
Smalltalk := nil
一発で固まりました。よしよし。
trueとfalse、入れ替わってる〜?
Smalltalkにはbecome:
という素晴らしい操作があります。こいつは、2つのオブジェクトのアイデンティティを入れ替えてしまうというものです。代入と違って、オブジェクトメモリ中でのアイデンティティそのものを変更してしまうので、その波及効果はオブジェクトメモリ全域に及びます。にやり。
true become: false
これまたすぐに固まりました。よしよし。
#無限の再帰で走りだす♪
これは多くのプログラミング言語で使える、無限再帰によるスタック食いつぶしです。みなさんが新しい言語を学んだらまず最初に試す、例のあれです。にやり。
| block |
block := [block value].
block value
はい、ちょっと時間がかかりましたが、ちゃんと固まりました。よしよし。
Object subclass: Process
Smalltalkではプロセス(グリーンスレッド)もオブジェクトです。このProesss
クラスの定義は、Smalltalkの盲腸と言われて久しいもので、これがなんとLink
クラスのサブクラスなんです。
おお、Process
よ、実装継承とはなさけない。というわけで、こいつをObject
のサブクラスにしたいのだけど、なかなかうまくいかないという話を昔聞いたような。そうだよね、自分を動かしてるプロセスのクラス定義を変えるとかね、VMともガッツリつながってそうだしね、いかにもヤバそうだよね。にやり。
Object subclass: #Process
instanceVariableNames: 'nextLink suspendedContext priority myList name env effectiveProcess terminating'
classVariableNames: 'PSKeys PSKeysSema'
package: 'Kernel-Processes'
お、Processの定義を変えちゃいかんという警告が。
いいぞ、そうこなくっちゃ。もちろん、自爆スイッチぽちっとなする時には、警告なんて読まずにOKボタンですよね。というわけで、Proceedを押します。
…あれ、壊れない。普通に動いてるぞ。
念のためにProcessBrowserで覗いてみると…
なんか、ちゃんと動いているように見える。残念ながらこの自爆スイッチは壊れているようだ。ち。
もしかして、bootstrapプロジェクトのせいおかげでしょうか?
おわりに
Smalltalkには他にも自爆スイッチがたくさんあります。自爆スイッチの場所を知ることで、自爆スイッチに鍵をかけることも可能になります。例えば、再帰自爆に対する防御のように技術的な対処も可能になります。
さあ、みなさん、ご安全に