I'm a n00b at using underscore/node and am trying to understand the concept of chaining functions. However, I cannot elicit proper outputs when trying to chain functions in node. Grabbing the example snipp from underscore's chaining section produces 'Invalid REPL keyword':
var __ = require("underscore"); //for underscore use in node
var lyrics = [
{line: 1, words: "I'm a lumberjack and I'm okay"},
{line: 2, words: "I sleep all night and I work all day"},
{line: 3, words: "He's a lumberjack and he's okay"},
{line: 4, words: "He sleeps all night and he works all day"}
];
__.chain(lyrics) //in the console chain appears to run and return correctly, but then
.map(function(line) { return line.words.split(' '); }) //Invalid REPL keyword
.flatten() //Invalid REPL keyword
.reduce(function(counts, word) {
counts[word] = (counts[word] || 0) + 1;
return counts;
}, {}) //Invalid REPL keyword
.value(); //Invalid REPL keyword
Am I a victim of ASI in this case? If so where is the ';' trying to be inserted? I am confused since plugging this snippet into JSHint produces no errors. Can one of you please help me identify the error?
Thanks!
I guess in a way you are running into ASI in that generally semicolons are inserted to separate expressions. In a more general sense though, what you are doing is typing into Node's REPL (what you get when you run node
with no args), and in a REPL environment, if a line can be executed on its own, it will and its result will be printed out.
This is different from a standard JS environment, which will fully process an entire function/file before executing it.
The error you are getting, Invalid REPL keyword
, is because Node's REPL has a set of commands that all begin with .
, such as .clear
(the full list is here), and .map
and such are JS functions, not REPL commands.
So for example if I take your example and reorder the .
s to the end of the line (so that each line can't be processed on its own), it will work in the REPL:
var __ = require("underscore"); //for underscore use in node
var lyrics = [
{line: 1, words: "I'm a lumberjack and I'm okay"},
{line: 2, words: "I sleep all night and I work all day"},
{line: 3, words: "He's a lumberjack and he's okay"},
{line: 4, words: "He sleeps all night and he works all day"}
];
__.chain(lyrics).
map(function(line) {
return line.words.split(' ');
}).
flatten().
reduce(function(counts, word) {
counts[word] = (counts[word] || 0) + 1;
return counts;
}, {}).
value();
Really though, the only time you should be using the REPL is for quick tests, where the single-line behavior is usually helpful. When doing normal development, you should work in a file and run node <filename>
to test your code.