LoginSignup
9
8

More than 5 years have passed since last update.

REPLでUnderscore.jsを使うと困ったことになる

Last updated at Posted at 2012-09-21

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の普通のコード内で使うときは何の問題もありません。

それにしても、できれば、こういう「公共的?」ツールでグローバルに余計な変数を使わないで欲しいです。

まぁ、使いたければ、慣れれば良いのでしょうけれど、、、

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8