コンテクスト管理と私 - Consistent Context
皆様あけましておめでとうございます。年末年始はフィットネスローラーをしながら預金通帳を眺めてました。やっと立ちコロできるようになりました。地味に嬉しいです。今年も宜しくお願いいたします。
さて、全然関係ありませんがブラウザには「戻る」「進む」ボタンがあります。 これは普通にページを見ている分には大変便利な機能なのですが…
一方で、ブラウザを使った「システム」を作る場合には、 これはかなり厄介な機能なのです。なぜか?
遠い昔、コンピュータへの指示はこんな風※に行っていました。
※ラッピングでぐりぐり配線してた、という方もいらっしゃるでしょうが、それはまた別のおはなし。
10 PRINT "アナタノネンレイハ?" 20 INPUT A 30 PRINT "アナタノネンレイハ";A;"サイ デスネ。ヨロシイデスカ?(Y/N)" 40 INPUT C$ 50 IF C$<>"Y" THEN 10 60 PRINT "アナタノネンレイハ";A;"サイ デス。" 70 END
1960〜1970年代生まれの方にはお馴染みの方もいらっしゃるかと思いますが、 これは1980年代当時のコンピュータに搭載されていた「BASIC言語」と呼ばれるものです。
ざっくりと解説すると、左端の数字が「指示の順番」を意味する「行番号」と 呼ばれるもので、この順番に指示が実行されていきます。
10番では「アナタノネンレイハ?」と画面に表示し、
20番ではキーボードから年齢の入力を待ち、
30番では文章と入力された年齢を表示し、
40番で確認の入力を求めます。
50番で入力が"Y"(Yesの意味)でなければ、10番に戻ります。
60番に来たということは確認が取れたということなので、断定的に表示して、
70番で終了、というわけです。
例えばこれを実行してみると… ※青字下線部はユーザ入力
run アナタノネンレイハ? ? 18 アナタノネンレイハ 18サイ デスネ。ヨロシイデスカ?(Y/N) ? Y アナタノネンレイハ 18サイ デス。 Okとなるわけですね。
さて、これと同じことをブラウザでやろうとしてみるとしましょう。
画面はそうですね、「年齢入力画面」「年齢確認画面」「年齢出力画面」の 3画面があればいいでしょうか。
まあ適当に、
input.cgi※とかconfirm.cgiとかoutput.cgiとか作れば良さそうな気がしますが…
※ 拡張子はcgiでもphpでもdoでもaspでもtspでも何でもいいです。
でも上のBASIC版と決定的に違うところがあります。
それは、利用者が自分の意志で「戻る」「進む」ボタンを押せること。
もっと言えば、利用者が(前段をすっとばして)いきなりoutput.cgiに
来ることもあるかもしれません。
難しく言えば、ブラウザ上のシステムは
「イプシロン遷移しまくりな決定性有限オートマトン」なのです。
意味わかんないですね。
まあ要するに、BASIC版では「決められた実行順にちゃんと従って実行される」 ということが保証されていたので、わりと直感的に指示が書けたわけなのですが、
ブラウザ上のシステムでは、 「実行順がどうなるかわからないので、いきなりoutput.cgiに来るなんていう ケースも含めてあらゆる場合を想定して動作を検証しておかなければならない」 のです。
これは画面遷移のあるなしには関係なくて、AJAXな通信でも同様です。 ていうか最近だとむしろAJAXの方が検証が甘いかもしれませんね。
この検証があまりにも面倒なので、弊社プラットフォームのcgiosでは ちゃんとOSばりのコンテクスト管理(最近は「継続」の管理とも)を行うことで、 この辺の面倒さを軽減しています。
例えば、Javaで(Javaにはgotoないのでこれはpseudo-codeですが)
public class SampleWebApp { /* 注文入力、確認、登録を司るフロー */ public static void main() { Order o = new Order(); /* 注文オブジェクト */ Form f; /* フォームの入力値を受け取るオブジェクト */ INPUT: System.out.printHtml(“input.html”); /* 入力画面をブラウザに表示(ここでcontext switch)*/ f = new Form(System.in); /* 入力待ち:ブラウザからのPOSTデータを受け取る */ if (f.action.equals(“next”)) { /* 「次へ」ボタンが押されたら */ o.receive(f); /* 入力値のセット */ if (o.validate() == false) goto INPUT; /* 誤りがあればもう一度入力 */ goto CONF; } goto INPUT; /* 実行順制御にwhile, forを使ってもよい */ CONF: System.out.printHtml(“confirm.html”); /* 確認画面表示 */ f = new Form(System.in); /* 入力待ち */ if (f.action.equals(“back”)) goto INPUT; /* 「戻る」ボタン→入力ページに戻る */ else if (f.action.equals(“execute”)) goto EXECUTE;/* 「保存」ボタン→入力データの保存へ */ goto CONF; EXECUTE: o.save(); /* DBに保存 */ DONE: System.out.printHtml("done.html"); /* 登録完了画面表示 */ exit(0); } }とか書けたとしたら、素敵だと思いませんか?struts.xmlとか書かなくていいし:)
最近はせっかちな世相を反映してか略語流行りだそうで、
「あけおめことよろ」→「あけよろ」などと略すのがよいらしいのですが、
そのlimをとると「あけよい(お年を)」などとなるのでしょうか。なんかだるいですね。
ではまた次回お会いしましょう。さようなら。