SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

「Web AI」ライブラリの使い方と内部仕様
- Web上のデータからJavaScriptだけで人工無脳を作成

ダウンロード sample.zip (16.7 KB)

検索のメソッドチェーン化の仕組み

 以下、「Web AI」の内部仕様について書いていきます。まずは、「検索のメソッドチェーン化の仕組み」についてです。

 メソッドチェーン化のプログラムは非常に単純です。命令を格納する配列に、引数と実行関数をセットにした連想配列を追加して、順番に実行しているだけです。以下、最も簡単な処理を行うadd()メソッドの「命令の登録」と「実際の実行」のプログラム部分を掲載します。

JavaScriptのソース:命令の登録と実際の実行
/*
 *------------------------------
 * 命令の登録
 *------------------------------
 */
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」実行のサンプルでも、この自動展開引数を使ってプログラムを記述しています。以下、その該当部分を抜き出して掲載します。

JavaScriptのソース:固定値で書いた場合
loop : 2,       // ループ回数
key : qStr,     // 検索キーワード
JavaScriptのソース:関数で書いた場合
loop : function() {
  // ループ回数を動的に決定
  return (kwArr.length >= 2) ? 2 : kwArr.length;
},
key : function() {
  // キーワードをループ毎に取り出す(cWSrch.loopCntはループのカウント数)
  return kwArr[cWSrch.loopCnt];
},

 上記のように、引数をあらかじめ固定値として記入する以外に、関数としても記述できます。この仕組みを利用することで「何が戻ってくるのか分からない通信処理の結果」を、柔軟に利用できます。

 この自動展開引数は、以下のような単純なコードで実現しています。

JavaScriptのソース:自動展開引数
function getPrm(obj) {
  if (obj) {
    if (obj instanceof Function) {
      return obj();
    } else {
      return obj;
    }
  }
  return null;
}

 WebSrchでは、このgetPrm()メソッドを利用して、引数から値を取り出しています。そうすることで、固定値の場合はそのままの値を、関数の場合はその実行結果を、命令の実行開始ごとに取得しています。

次のページ
クエリー圧縮によるデータの保存

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5567 2010/11/18 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー