検索のメソッドチェーン化の仕組み
以下、「Web AI」の内部仕様について書いていきます。まずは、「検索のメソッドチェーン化の仕組み」についてです。
メソッドチェーン化のプログラムは非常に単純です。命令を格納する配列に、引数と実行関数をセットにした連想配列を追加して、順番に実行しているだけです。以下、最も簡単な処理を行うadd()メソッドの「命令の登録」と「実際の実行」のプログラム部分を掲載します。
/*
*------------------------------
* 命令の登録
*------------------------------
*/
this.add = function(arg) {
// 「引数」と「その引数を処理する関数」を登録
this.pushCmnds({prm : arg, fnc : doAdd});
// メソッドチェーン化するためにthisを戻す
return this;
}
/*
*------------------------------
* 実際の実行
*------------------------------
*/
function doAdd(arg) {
if (arg) arg(); // 引数を関数として実行
nextExec(); // 次の命令を実行
}
このプログラム中のpushCmndsが、引数と処理を命令配列に格納するためのメソッドです。このpushCmndsは命令の挿入場所をコントロールしながら命令を追加していきます。通常は、命令配列の末尾に命令を追加します。また、挿入モードがオンの場合は、現在実行中の命令の直後に、新しい命令を追加していきます。
nextExec()は、命令の実行フォーカスを次に移す命令です。命令の実行は、命令配列の末尾までくれば自動で停止します。また、コールバック系の命令では、処理が終了した時点でこのnextExec()が呼び出されるようになっています。そのため、非同期で実行される通信処理も、メソッドチェーン化して直列に処理を記述できるようになっています。
これらの命令の内部処理は、煩雑になりますので、コメント付きのソースコードをご覧になってください。ソースコードは、「Web AI」のサイト上で、全て閲覧できるようになっています。
自動展開引数の仕組み
「Web AI」のメインオブジェクトであるWebSrchは、そのメソッドの多くで自動展開引数を使っています。
自動展開引数では、引数が固定値の場合はその値を直接利用して、引数が関数の場合は命令実行の冒頭で関数を実行して、その戻り値を引数として利用します。また、処理にループの設定がある場合は、ループが行われるごとに関数を実行します。
この仕組みを利用することで、直前の処理で得た値を元にして、引数の内容を動的に変更する処理が簡単に記述できます。具体的には、直前の検索結果からキーワードを取り出して、そのキーワードを組み合わせて新しい検索クエリーを作成するといったことができます。
先に掲載した「Web AI」実行のサンプルでも、この自動展開引数を使ってプログラムを記述しています。以下、その該当部分を抜き出して掲載します。
loop : 2, // ループ回数 key : qStr, // 検索キーワード
loop : function() {
// ループ回数を動的に決定
return (kwArr.length >= 2) ? 2 : kwArr.length;
},
key : function() {
// キーワードをループ毎に取り出す(cWSrch.loopCntはループのカウント数)
return kwArr[cWSrch.loopCnt];
},
上記のように、引数をあらかじめ固定値として記入する以外に、関数としても記述できます。この仕組みを利用することで「何が戻ってくるのか分からない通信処理の結果」を、柔軟に利用できます。
この自動展開引数は、以下のような単純なコードで実現しています。
function getPrm(obj) {
if (obj) {
if (obj instanceof Function) {
return obj();
} else {
return obj;
}
}
return null;
}
WebSrchでは、このgetPrm()メソッドを利用して、引数から値を取り出しています。そうすることで、固定値の場合はそのままの値を、関数の場合はその実行結果を、命令の実行開始ごとに取得しています。
