node.jsのRead-Eval-Print-Loop (REPL) は手軽にコードを試せて便利ではあるのですが、少し癖があるので注意も必要です。
たとえば、REPL Features を読むと、
http://nodejs.jp/nodejs.org_ja/docs/v0.8/api/repl.html#repl_repl_features
「特別な変数である _ (アンダースコア) は一番最後の式の結果を保持します。」
と書いてあります。
そこで、数あるnpmパッケージで最もDependedされているパッケージであるUnderscore.jsを使うとどうなるのでしょう?
インストール
npm install underscore
問題なく入ります。
REPL起動して読み込む
$ node
> var _ = require('underscore');
undefined
>
はい、ここまでは問題ありません。
さて、では、mapとかやってみます
> _.map([1, 2, 3], function(num){ return num * 3; });
TypeError: Cannot call method 'map' of undefined
at repl:1:3
at REPLServer.self.eval (repl.js:111:21)
at rli.on.e (repl.js:260:20)
at REPLServer.self.eval (repl.js:118:5)
at Interface.<anonymous> (repl.js:250:12)
at Interface.EventEmitter.emit (events.js:88:17)
at Interface._onLine (readline.js:199:10)
at Interface._line (readline.js:517:8)
at Interface._ttyWrite (readline.js:735:14)
at ReadStream.onkeypress (readline.js:98:10)
あれ?
まったく同じコードを、Underscore.jsを読み込んだブラウザChromeのコンソールでも試してみます。
>_.map([1, 2, 3], function(num){ return num * 3; });
[3, 6, 9]
ちゃんと動いてます。
REPLにもどります
じゃ、_の中身はどうなってるんだ?
> _
undefined
そうです。REPLでは、
>_ (アンダースコア) は一番最後の式の結果を保持します。
$ node
> var _ = require('underscore');
undefined ←これ?
>
じゃ var とったら?
> _ = require('underscore')
{ [Function]
_: [Circular],
VERSION: '1.3.3',
forEach: [Function],
each: [Function],
collect: [Function],
map: [Function],
inject: [Function],
foldl: [Function],
reduce: [Function],
(略)
おおっ
> _.map([1, 2, 3], function(num){ return num * 3; });
[ 3, 6, 9 ]
やれば出来るじゃないか!
念のためにもう一回
> _.map([1, 2, 3], function(num){ return num * 3; });
TypeError: 1,2,3 is not a function
at Array.map (native)
at repl:1:3
at REPLServer.self.eval (repl.js:111:21)
at rli.on.e (repl.js:260:20)
at REPLServer.self.eval (repl.js:118:5)
at Interface.<anonymous> (repl.js:250:12)
at Interface.EventEmitter.emit (events.js:88:17)
at Interface._onLine (readline.js:199:10)
at Interface._line (readline.js:517:8)
at Interface._ttyWrite (readline.js:735:14)
ダメでした(^^;;
というわけで、仕様には素直に従いましょう。
REPLでは、特別な変数である _ (アンダースコア) は一番最後の式の結果を保持します。
ということで、どうしてもアンダースコアを使いたければ、_ (アンダースコア)ではなく、他の変数名を使えばよいのです。
もちろん、REPLではなく、node.jsの普通のコード内で使うときは何の問題もありません。
それにしても、できれば、こういう「公共的?」ツールでグローバルに余計な変数を使わないで欲しいです。
まぁ、使いたければ、慣れれば良いのでしょうけれど、、、