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 もの自社製でオープンソースなモジュールを使っているなんてすごいですね!
学園祭当日どんな話が聞けるのか楽しみです!!