node-isaacs

この記事は 東京Node学園祭2012 アドベントカレンダー : ATND の 12 日目の記事です。
僕の記事で大分ハードルが下がったと思います。まだまだ参加者募集中です!

npm モジュールランキング No.2

node-isaacs は 東京Node学園祭2012 で来日される substack(James Halliday) さんのモジュールです。
npm モジュールランキングは同じく substack さんの npmtop で確認する事が可能です。

$ npm install npmtop -g
$  npmtop
rank   percent   packages   author
----   -------   --------   ------
   1    1.25 %      221     tjholowaychuk
   2    1.05 %      186     substack
   3    0.77 %      136     raynos
   4    0.70 %      123     dominictarr
   5    0.66 %      117     coolaj86
   6    0.54 %       95     architectd
   7    0.49 %       87     jaredhanson
   8    0.47 %       83     isaacs
   9    0.46 %       82     damonoehlman
  10    0.46 %       82     marak
  11    0.44 %       78     fractal
  12    0.43 %       76     gozala
  13    0.40 %       70     indexzero
  14    0.38 %       67     balupton
  15    0.37 %       65     ryanflorence

$ npmtop --who mikeal   
rank   percent   packages   author
----   -------   --------   ------
  78    0.14 %       25     mikeal

今回来日される海外スピーカーの皆さんはこんな感じのランキングなんですね。

※ ブログ執筆時点(2012/10/26)のランキングです。

新しいゲートキーパー

このモジュール は言わずと知れた New gatekeeper Isaac Schlueter 氏の誕生日に彼の為に書かれたモジュールとされています。

使い方は README.md に書かれている通りですが、一番シンプルなのは

$ npm install isaacs -g
$ isaacs -n 3
ok so i write the robots
support them we should windows usually. allowed on are also forward slashes cygwin uses
but if you specify a url? to a full absolute path, would that break npm? Error: ENOENT, directory '/usr/local/lib/node/.npm/connect/0.2.1-LINK-26633a47/package/bin/connect' No such file or

$ isaacs
> oh hello
it (for and testing the sample working on of time a lot you are I do using env, what should
> pretty much
to go smart way probably a decided it's well. I parser and just studied ryan's http
> you can do it, you just have to have belief in belief
I'll just randomize it it is so people keep thinking

とグローバルインストールして、オプション n で行数を指定する、またはインタラクティブにキーワードを入力して会話を楽しみます(笑)

node-markov

isaacs コマンドの実体は bin/cli.js ですが、この中で最終的に izs.speak() しています。これは index.js 30行目から33行目 で定義されていて、その前の行で node-markov の markov オブジェクトが作成されています。 このオブジェクトはデフォルトの order が 2 に設定されていて、引数に設定された order で seed が実行された際に辞書の様な物を作ります。 仮に markov(2).seed('This is a test.') したとすると、内部の db という変数に以下の様に格納されます。

db: { this_is: 
   { count: 1,
     words: { 'This is': 1 },
     next: { a_test: 1 },
     prev: { '': 1 } },
  a_test: 
   { count: 1,
     words: { 'a test.': 1 },
     next: { '': 1 },
     prev: { this_is: 1 } } }

isaacs コマンドが実際にやっている事は結構単純で、引数なしの時はコマンドラインから入力されたキーワードを元に respond を呼び出し、引数 n で行数指定された時は pick で適当な文字列を取り出し、それを respond に渡して結果をスペース区切りで join して出力しているだけです。

respond 内部では与えられたキーワードを search して、該当するキーワードがない場合は pick しています。 pick は node-deck というモジュールを使って先ほどの変数 db からランダムに key を返しています。

respond は最終的にキーワードか pick から帰ってくる key を元に fill を呼び出し、引数に合致する words から前後を順番に配列に unshift しています。結果的に以下の様な感じになります。

$node -e "var m = require('markov')(); m.seed('This is a test for markov.'); console.log(m.respond('This is'))"
[ 'for markov.', 'a test', 'This is' ]
$node -e "var m = require('markov')(); m.seed('This is a test for markov.'); console.log(m.respond('a test'))"
[ 'for markov.', 'This is', 'a test' ]
$node -e "var m = require('markov')(); m.seed('This is a test for markov.'); console.log(m.respond('for markov'))"
[ 'This is', 'a test', 'for markov.' ]
$node -e "var m = require('markov')(); m.seed('This is a test for markov.'); console.log(m.respond('is this'))"
[ 'for markov.', 'a test', 'This is' ]
$node -e "var m = require('markov')(); m.seed('This is a test for markov.'); console.log(m.respond('is this'))"
[ 'for markov.', 'This is', 'a test' ]

Stream

ところで node-isaacs では seed に stream が使われています。node-markov は stream も seed として受け取れる様になっています。
このファイルはどうやって作られたかというと インストール時curl で読み込まれていました。
http://substack.net/data/isaacs.txt

package.json はこんな事も出来るんですね。でもセキュリティ的にどうなんだろう。

ちなみに substack さんは The Stream Handbook という本を書きはじめています。完成が楽しみな原稿です。

https://github.com/substack/stream-handbook

この原稿は日本Node.jsユーザー会の代表である meso さんが翻訳しているので英語が苦手な方でも大丈夫です。

https://github.com/meso/stream-handbook

まとめ

このモジュールを見つけたのは彼の同僚 pkrumins(Peteris Krumins) さんのこの記事を見たからでした。

http://www.catonmat.net/blog/browserling-open-sources-90-node-modules/

少し古い記事ですが、一つのプロダクトに 90 もの自社製でオープンソースなモジュールを使っているなんてすごいですね!

学園祭当日どんな話が聞けるのか楽しみです!!