「んははははははははははは。まべ・・じゃなかった。その名前はここではご法度だったな。ルビイよ。元気そうでなによりだ。ウムウム」

吟遊パソコン長七郎、いや、現時点では真紅の父親、実装寺健一郎にハッキングされたソニーのノートパソコンVAIOは、空中にふわふわと浮かびながら、スピーカー音量最大で、高らかに叫んだ。

氷の魔女ゲルダは、ぱっかーんと口を開けてそれを見ている。

「コホン。えーと、少しばかり発言を許していただけるかな、ゲルダよ。紹介しておこう。彼こそわれらが旅の仲間にしてルビイ・サーガの記録者、吟遊パソコン松平長七郎殿じゃ。しかし、今はどうやらルビイの父君に意識を乗っ取られておるようじゃがな」ガフンダルは、ゲルダに長七郎を紹介する。

「あいや我が君、パソコンとはなんじゃ?」

「このルビイが住まいしておった世界ではポピュラーな造り物でな。人間の代わりに複雑な計算をしてくれるものじゃ。本来無機物の集合体であるゆえ、このように自ら喋ったり、ましてや宙に浮いたりはせぬが、これもビャーネ神の偉大かつ深遠なる所業なのか、こうして人格を持つようになっておる」

「ふーん。こりゃまた面妖なる代物じゃのう。して、小娘の父親はその異世界からこのようにして通信してきておるのか?その父親も魔道を能くするのかえ?」ゲルダは興味津々でガフンダルにたずねる。

「うーむ。さすがのワシにも何がどうなっているのかよくわからぬゆえ、魔道といってもよいかもしれん。よし。これ、ルビイよ。父君の名前はなんと申すのだ?」

「えーっと。健一郎、実装寺健一郎だけど・・・」

「おおそうか」何を思ったか、ガフンダルは玉虫色のコートの襟を正し、背筋をぴんと伸ばして、なにやら口上を述べ始めた。

「異界の魔道師、実装寺健一郎殿よ。よくぞこのノルゴリズムにおいでなされた。心より歓迎いたしますぞ。吟遊パソコン長七郎殿の意識を乗っ取って、この世界に出現なされたところを見ると、貴殿も相当なる魔力の持ち主とお見受けいたしますぞ。畏怖と敬意の心をもて、この『玉虫色のガフンダル』より、『群青色のケンイチロー』というふたつなをお贈りいたしましょうぞ」

「ちょっとぉ。ガフンダルってば。ヘンなあだ名プレゼントしないでよ。それでなくてもノリ易いタイプなんだからさ。パパは」

VAIOは、つーっと空中を滑るようにガフンダルの目の前まで移動し、そこでぴたりと静止する。

「玉虫色のガフンダルよ。そのふたつな、喜んでお受けいたしましょうぞ」

「ほーら。始まっちゃったわよ」

「ガフンダル殿には、我が娘ルビイがいつもお世話になっているようだ。この通り謹んでお礼申し上げる。また、どうかわが妻にして、娘の新しい母親、洋子の魂救出のその日まで、なにとぞよしなにお願いいたしますぞ」

「しかと承りました」

― なあに芝居がかったことやってんだろ。馬鹿じゃないの?なんか、あっという間に意気投合しちゃってさ。そもそもお義母さんがあんなことになっちゃったのはパパのせいじゃない。仕事中心のパパがいけないんだわ。それに、この世界にワタシを引きずり込んだ張本人はガフンダルかもしれないのよ。さすがは玉虫色と群青色ね。いろんな色が混ざり合わさっちゃって、両方とも怪しさ爆発だわ。その点ワタシなんでルビイだから、真っ赤よ、真っ赤。混ざり物のない原色なんだからね ―

色のことなどという、あらぬ方向へ考えがさまよいだしてしまった真紅であるが、口に出しては言わなかった。どうやら今回の冒険で、思ったことをすぐ口に出すと、ろくな結果を招かないということを徐々に学習しつつあるようであった。

真紅がそんなことを考えていると、父親の乗り移ったVAIOは、またつつーっと空中を移動し、キャプテン・ハックの前に静止した。

「お初におめにかかる。キャプテン・ハック殿。私はルビイの父親にして、玉虫色のガフンダルが盟友、群青色のケンイチローと申すもの。以後お見知りおき願いたい」

― いきなり自分で名乗ってるわ、群青色なんて。ほんと馬鹿だわ。自分の父親ながら ―

「こちらこそよろしく頼むぜ。群青色さんよ」キャプテン・ハックが、面倒くさそうに返答を返す。

「時にキャプテン・ハック殿。まさかとは思うが、貴殿はうちのルビイに対して、ヨコシマな劣情を抱いておらんだろうな。あれはまだまだ子供だから、くれぐれも間違いのないようお願いしたい」

「な。なにい。ま、まあ将来はどうかしらねえが、今はそんな気を起こすことはねえだろな。俺はどっちかっていうと、成熟したオンナが好みだからよ。例えばあのゲルダさんみたいによぉ」

「そうか。それなら安心だ」

― あ。傷つくぅー。もう子供だって産めるんだからね!ワタシ。くっそー。今に見てらっしゃい。 ―

何をどう、今に見てもらえばいいのか皆目見当がつかなかったが、とにかく真紅はそう決意した。

「あのう。えーっと。お取り込み中申し訳ないが、ええーっと。わらわのクイズのほうはその、どうなっておるのかえ?」ゲルダが心配げな様子で、誰に言うでもなく、ポツっと呟いた。

「おうそうだ。まべ・・じゃなかったルビイ、一緒にあの柱の影へ行こう。作戦会議をする。キャプテン・ハックも来てくれ。ガフンダル殿は、我々がいんちきしていると思われるとまずいので、ここに残っていてもらおうか」

そういって、VAIOは、また空中を滑るように、部屋の隅の柱に向かって移動しだした。

「ささ。はやく」と二人を促す。

真紅とキャプテン・ハックは、お互い顔を見合わせて怪訝な表情をしつつも、VAIOの後を追って歩き出す。

三人(一台と二人)が、柱の陰に集まると、群青色パソコン健一郎が、やおら話し始めた。

「年齢当てクイズを攻略するために、百五減算のアルゴリズムを使ってみたいと思う」

「ひゃ、ひゃ・・あるごるご」あわあわしている真紅を制して、健一郎は話を続ける。

「百五減算とは、未知の数を3、5、7でそれぞれ除算した余りから求めるという、江戸時代より伝わる和算法のひとつなのだ。いいか。百五演算だぞ。大工の源さんではないので注意が必要だ」

「ごめんなさいパパ。今、ギャグをぶちかましたみたいなんだけど、よくわからないの」

「コホン。えーっと。説明するより実際にやってみたほうが話は簡単だ」

健一郎がそういうと、液晶モニタ部に、なにやらウインドウが出現した。

「これは、私が突貫工事にてでっち上げた年齢当てアプリケーションだ。当然Rubyでできているぞ。ルビイの年齢は私も知っているので、キャプテン・ハックよ。君に質問しよう。まず君の年齢を3で割った余りはいくつだ?」

「えーっと。2だな」

「では、5で割った余りは?」

「3」

「では最後に7で割った余りはいくつかな?」

「同じく3だな」

キャプテン・ハックの答えた数が、テキストボックスにぽつぽつっと現れる。

「よおし。ではルビイ、そこの【推理】ボタンを押してみてくれたまえ」

「なんか、馬鹿馬鹿しいような気もするけど・・・。はい」真紅が推理ボタンを押すと、ダイアログボックスがぽよんと飛び出してきた。

「えーっと。なになに。『あなたの年齢は38歳ですね。そうでしょう?隠してもわかりますよ』ええぇー!?ハックって38歳なの?うそ」

「残念だがズバリ的中だね」ハックはなんとなく照れくさそうに頭を掻いている。

「なあんだ。どこに出しても恥ずかしくないおっさんじゃん、ハックったら。馬鹿みたい」

「馬鹿みたいって言い草はねえだろ!38歳っていってもまだまだ現役だぜ。若い奴らにゃあ負けねえ」キャプテン。ハックは、顔を真っ赤にして叫ぶ。

「なにが現役なんだか。でもすごい。当たるのねこれ。えーっと。私の場合は、13歳だから、3で割ると余りは1、5で割ると余りは3、7で割ると6でしょ。じゃあ、【推理】っと。んきああー。13歳。当たったわぁー!」ものすごいはしゃぎようの真紅。

「ルビイ。どうやらプログラムの威力にひれ伏した様子だな。ではソースコードを見てみようか」

001 | <html>
002 | <head>
003 | <meta http-equiv="Content-Style-Type"
    content="text/css" />
004 | <link rel="stylesheet" type="text/css"
    href="style.css" />
005 | <title>Ruby・イン・ワンダーランド【百五減算
   年齢当てプログラム】</title>
006 | <script language="RubyScript">
007 | ##############################
008 | # 105減算アルゴリズム
009 | # By 実装者 2008/11
010 | ##############################
011 | def init()
012 |     #Rubyのヴァージョンを初期表示します。
013 |     @window.document.getElementById
      ("version").innerHTML = RUBY_VERSION
014 | end
015 | def main()
016 |     #メイン処理です。
017 |     begin
018 |         #入力された値の検証を行いつつ、
       変数に格納していきます。
019 |         a = Integer(@window.div3.value)
020 |         b = Integer(@window.div5.value)
021 |         c = Integer(@window.div7.value)
022 |         if a<0 || b<0 || c<0 then
023 |             rize  #マイナス値が存在すればエラー
024 |         end
025 |         #これが、105減算のメインロジックです。
                 たった1行!
026 |         solv = (70 * a + 21 * b + 15 * c) % 
        105
027 |         # 結果発表
028 |         @window.alert "アナタの年齢は" +
        solv.to_s + 
              "歳ですね。\nそうでしょう?
             隠してもわかりますよ"
029 |     rescue
030 |         # Integer()で数値変換できない場合、
       TypeErrorまたはArgumentErrorが発生する。
031 |         @window.alert "数字を正しく入れてね"
032 |     end
033 | end
034 | </script>
035 | </head>
036 | <body class="body" onload="init"
      language="RubyScript">
037 | <center>
038 | <h1>Ruby百五減算</h1>
039 | <hr>
040 | <h2>Rubyが貴方の年齢を当ててごらんにいれます</h2>
041 | アナタの年齢を3で割った余りは?: 
   <input type="text" id=div3 name=div3><br />
   <br />
042 | アナタの年齢を5で割った余りは?: 
   <input type="text" id=div5 name=div5>
      <br /><br />
043 | アナタの年齢を7で割った余りは?:
      <input type="text" id=div7 name=div7>
      <br /><br />
044 | <input type="button" value="推理" 
      id=start name=start 
      onclick="main" language="RubyScript">
045 | </center>
046 | <hr>
047 | <span style="margin-left: 90%">Ruby 
      <span id="version"/>
      </span>
048 | </body>
049 | </html>

「さよなら」奇しくも声をそろえてそういいながら、慌ててその場を立ち去ろうとする真紅とキャプテンハックである。

「これこれ。どこへ行こうというのかね。頼むよ。解説させておくれよ。もう独白形式でRubyの解説をするのはやめたので、この場をお借りするしかないのだよ。今回だけだから。ね、ね。今後はプログラムも大きくなってくるので、この場で全部ソースコードを載せるのは無理と思うし。ね、ね」

「何わけのわからないこといってんの、誰に何を訴えてるわけ?パパ。まあ好きにすれば」

「群青色健ちゃんの、Ruby解説こぉなぁー!」



勝手にコーナーを立ち上げないでくれ、実装寺健一郎よ。


ソースコードを一瞥していただくとお分かりであろう。これは世間一般的にいうと、HTML形式というカテゴリに属するものだ。

このコードがWebサーバから送信されてくると、Webブラウザが『ははん。これはどうやらHTML形式で記述されているぞと判断し、文字の色や大きさを変えたり、別の場所から絵を持ってきたり、飾りつけしたりなどして画面に表示するのである。

だが、このコードは、ただのHTMLコードとはわけが違うのだ。どこがどう違うのかというと、一般的にHTMLは静的なもので、ユーザはそれをただぼんやりと閲覧するだけのものなのだが、これは、ユーザの操作に反応するのである。

このようなインタラクティブ(対話式) Webページを構築する方法には二通りある。ひとつはサーバー側にその仕掛けを設置するもので、これをCGI、JSP、ASPなどと呼ぶ。

もうひとつは、クライアントのブラウザにスクリプトエンジンを持ち、それをHTMLコード内から操作するもので、このHTMLを特に、ダイナミックHTMLと呼ぶのである。

ダイナミックHTMLについては、以前『実装寺健一郎の独白2』で解説させていただいたので、ここでは割愛するが、多くの書籍が出版されているし(現在では、クライアントサイドのスクリプトと、 Webサービスを連動させるAjaxが主流となっているので、クライアントサイドだけで完結するダイナミックHTMLの解説本は少数派になっていきているのだが)、インターネットでは、気のいい兄さん達が、「もうわかったから」と許しを乞いたくなるほど解説してくれているから、情報を収集するのに困ることは絶対にあるまい。

ただし、それらの解説で使用されているのは、残念ながらJavaScriptであって、Rubyのものは皆無なわけであるが、実はそう悲観したものでもない。

JavaScript自体、そんなに難しい言語ではない。なぜなら、そもそも機能が、ブラウザ上でなにやら芸をするということだけに特化されているからなのである。

であるから、まずRubyの基本的な書法を覚えて、何万何十万のオーダーでネットに転がっているダイナミックHTMLサンプルのJavaScriptの部分をRubyで書き換えてみるのだ。

最初はあちらこちらでゴツンゴツンと頭を打つかもしれないが、慣れてくると、次第に成すべき事がわかってくるようになる。そうすれば、ダイナミックHTMLも、Rubyも、そしておまけにJavaScriptも習得できるという、一石三鳥こりゃたまりませんわ状態となるのだ。

もし貴方が調子乗り、もとい向上心に富んだ技術者であるならば、余勢をかって、PerlScriptに挑戦するのも一興かもしれない。PerlScriptとは、ご想像の通り、JavaScriptをPerlにて置き換えるものだ。

さて、話を前出のコードに戻そう。

このコードのまず一番のキモは、なんといっても6行目のScriptタグ、 <script language="RubyScript"> だろう。

ブラウザのHTML解析担当者に『ここからスクリプトが始まるのだが、そのスクリプトエンジンはRubyScriptだよ。どうぞよろしく』と教えているのである。
先ほど申し上げた、JavaScriptからRubyへの置き換えは、まず、<script language="JavaSctipt">から、<script language="RubyScript">へと書き換えるところから始まると心得ていただきたい。

Rubyのコードの中身に眼をやってみると、二つのメソッドが定義されているのがわかると思う。init()とmain()だ。それぞれ11行目と15行目から定義されている。

これらのメソッドは、いきなり勝手に動き出すわけではない。このHTMLコードによって構築されるページ上で、なにかイベントが発生し、それと連動して呼び出されるのである。

init()は、36行目のBodyタグで呼び出されている。

<body class="body" onload="init" language="RubyScript">

bodyのonload時、即ち表示される前に必ず呼び出されるのである。

initメソッドの中身を見てみると、47行目で定義されているspanに、Rubyインタプリタのバージョン番号を表示しているのである。RUBY_VERSIONというのは、『組み込み定数』と呼ばれるもので、Rubyインタプリタのバージョンを文字列として持っている。定数だから、勝手に書き換えることはできない。

init()メソッドは、たったの一行(コメントを入れると二行だが)のチンケなものなのだが、RubyScriptにとって、非常に重要なポイントが隠されているのである。

@window.document.getElementById("version").innerHTML = 
                     RUBY_VERSION

それは他でもない、先頭の@windowなのだ。これは明らかに変数なのだが、コードのどこを見ても、@windowという変数など定義されていないのだ。

Rubyでは、変数は必ず初期化されていなければ使えないはずだから、このプログラムは実行できないのかというと、そんなことはない。

ではこの@windowというのは何者なのかというと、『Webブラウザが保持するオブジェクト』なのである。JavaScriptも、VBSCriptも、PerlScriptも、そしてRubyScriptも、 Webブラウザが保持するオブジェクトにアクセスできなければ、まったくなにもできないのである。

ダイナミックHTML上のスクリプトエンジンである第一条件は、まず『 Webブラウザが保持するオブジェクトに自由にアクセスできること』であるわけだ。

従ってRubyScriptも、これらオブジェクトにアクセスする機能を持っているというわけである。

main()が、実際の百五減算を実行する、まさにメイン部分となるわけだが、これは、46行目で、推理ボタンをぷちっとクリックしたときのハンドラとして定義されているのである。

<input type="button" value="推理" id=start name=start 
  onclick="main" language="RubyScript">

main()の中では、まず3で除算した余り、5で除算した余り、7で除算した余りを入力するテキストボックスからそれぞれ値を取得してきて数値に変換し、百五減算処理を行って結果をダイアログに設定してぽこんと表示するということをやっている。

ここで注目していただきたいことがひとつある。それは、制御構造のパートでは解説しなかったのだが、制御構造の立派な一員である、『例外処理』が組み込まれているのである。

このプログラムは、三つの入力域を持っているわけだが、全てに正の整数を入れてもらうことを想定しているのだ。

ところが世の中にはひねくれ者がいるわけで、明らかに数値を入れなければならないところへ『にょほほーん』などという文字列をいれてプログラムを虐待するのである。

もしそれを見過ごしてしまったら、このプログラムはコケてしまう。そうならないようにしっかりと入力された値をチェックして、都合の悪い値ならば、その旨意思表示をし、態度を改めてもらわなくてはならないのである。

この百五減算プログラムでは、その仕組みに例外処理を採用した。

例外処理の構造は簡単に言うと次のようになっている。

begin
    # 例外が発生する可能性のある処理
rescue
    # 例外が発生したときの処理
end

beginとrescueで挟まれたステートメントで例外が発生すると、その場からいきなりrescue以降へ制御が移る。そして、endまでの処理が実行されるという構造になっているのだ。

このプログラムでは、例外が発生する可能性が高いのが、19、20、21行目の、 Integer組み込みメソッドで各テキストボックスの入力値を数値変換しているところだ。

もし数字以外の変な文字が入っていた場合、この Integerメソッドは例外を発生させるのである。さらに、整数に正しく変換されたとしても、マイナス値だと、ちょっと具合の悪い計算結果になる。そこで、三つの数値のどれかひとつでもマイナス値であった場合、無理やり例外を発生させて処理を中止するのである。それが、23行目のrizeなのだ。

この例外処理は、後々も出てくるので、しっかり記憶しておいていただきたい。

今回のプログラムは、以下のURLで動作を確認できるぞ。


但し、貴方のマシンにActiveScriptRubyがインストールされていないと動かないので、よろしくご了承願いたい。

コードの解説を退屈そうに聞いていた真紅は、終わりと見るや否や「よし。これでゲルダの年齢をびしっと当てるのよ。そして氷の水晶をゲットするんだ」と叫びざま、VAIOをむんずとつかみ、鼻息も荒くゲルダのところへ突進していった。

「これこれ。なんという馬鹿力なんだルビイ。父さん痛いよ」真紅は、哀願する父親の声など完璧に無視する。

「待たせたわねゲルダ。これから貴女の年齢をぴたっと当てて見せるからね。今から質問をみっつするから、正直に答えなさいよ」真紅は、ピンと背筋を伸ばして胸を張り、ゲルダをまっすぐ見つめて高らかに宣言した。

「いいとも。なんなと訪ねるがよいわ」ゲルダも同じように背筋を伸ばしてそう答える。

「じゃあいくわよ。ゲルダ、貴女の年齢を3で割った余りは?」

「わらわの年齢を3で割るのか?それの余り?えーっと。0じゃな」

「じゃあ、5で割った余りは?」

「3じゃな」

「これで最後よ。7で割った余りはいくつ?」

「4じゃ」

「わーっははははは」真紅は勝ち誇ったように高笑いする。「これでワタシの勝ちよゲルダ。覚悟しなさい!」

「なんだ?そんな質問でわらわの年齢がわかると申すのか?」

「申す申す。申しまくりよ。さあ、炸裂するがいい!【推理】ぼたぁぁぁーん。ぽちっとな。ん?げぇぇぇぇぇぇぇぇー!」

「どうしたんだよルビイ。どんな答えが出たんだい?」と、VAIOの画面を覗き込むキャプテン・ハック。だが彼には真紅の世界の文字など読めない。真紅は顔を高潮させて、キャプテン・ハックの腕を掴み、先ほどの柱の陰までダッシュで戻る。

「おい。ちょっと。痛てえってんだよ。もっと丁寧に扱ってくれねえか!?」キャプテン・ハックは、真紅のものすごい力にずるずると引きずられながら叫ぶ。

柱の陰に戻ると、真紅は小さな声で言った。

「ちょっとパパ。このプログラムおかしいんじゃないの?」

「失敬な。私のプログラム、というか、日本民族伝統の叡智を否定するのかね!キミは」

「そういうわけじゃないけど。あまりにあんまりな結果が出ちゃったからさあ。ちょっとパパのトシで試してみていい?」父親の年齢で試してみたが、これも正解であった。

「おっかしいわねぇ」しきりに首をひねる真紅。

「一体全体、ゲルダは何歳と出たのだ?ルビイよ」

「えーとね。18歳なの」真紅がぽつんと答える。

「じゅじゅじゅじゅ、じゅうはっさーい!??さーいさーいさーいさーいさーいさーいさーいさーぃ」



図らずも、キャプテン・ハックと実装寺健一郎二人の、いい具合にハモった魂の叫びが、氷の洞窟中にこだましたのであった。

旅立ち(7)へ続く
最終更新:2008年12月04日 15:50