Mongo.exe tries to execute commented lines in my JavaScript file?
I have a set of MongoDB Shell commands in JavaScript file.
use test;
/*
var categories = [];
var sum = 0;
var category = {
_id: "",
num: 0
};
var cur = db.itemdata.aggregate( [
{ $group: { _id: "$category" ,
num : {$sum: 1 }
}},
{ $sort: {"_id":1 }}
]).toArray();
for(var i=0; i < cur.length; i++){
sum += cur[i].num;
categories.push(cur[i]);
}
category.num = sum;
categories.unshift(category);
*/
/* Example 2 */
var category = 'Books';
var cnt = db.itemdata.find({"category" : category}).count()
print(cnt);
I'm getting the expected result for the code under Exampe2. however, I see some warning/info in the terminal.
2016-07-06T11:44:35.886-0500 E QUERY [thread1] SyntaxError: unterminated comment @(shell):3:0
2016-07-06T11:44:35.889-0500 E QUERY [thread1] ReferenceError: categories is not defined :@(shell):3:2
2016-07-06T11:44:35.891-0500 E QUERY [thread1] ReferenceError: categories is not defined :@(shell):1:1
3
bye
I executed the JavaScript file in windows machine using the following command/ syntax:
mongo.exe < script.js
Why am I seeing those error, even though the categories
variable is inside the commented block.
This is not a showstopper, would like to understand why it is happening?
This is probably due to the way mongo shell handles multi-line operations. The shell evaluates lines one by one unless it sees something that it thinks will span multiple lines, in which case it will start a "multi-line operation".
Using the mongo
command (without piping an input file to it), it might look something like this:
> 40 + 2;
> 42
> for(var i = 0; i < 2; i++) {
> ...
where 40 + 2
is evaluated at once, but the {
will tell mongo to wait its closing counterpart, }
, before evaluating the for loop.
This behaviour is documented here.
The problem is that /*
is not such symbol, so mongo won't wait for its friend */
. It will wait for one more line though, or until you give it something it thinks it can evaluate.
/*
var categories = []; *
*/
...
The above won't throw errors and will continue to wait further instructions, because both *
and /
are binary operators so mongo knows nothing good can come from evaluating a line that ends in those. So it will wait, and then if you'd add, say, 40 + 2
it would yield to 42
just fine because now the whole evaluated piece of code from /*
to 40 + 2
is valid JavaScript.
Perhaps that's not the most elegant way ever to determine whether or not to evaluate a line of input, but that's how it works now. Similarily,
/* {
var categories = [];
var sum = 0;
...other commented stuff..
}*/
would work because mongo will wait for the closing }
before evaluating. But that's probably not something you want to do every time you write a comment and it would leave the next developer wondering if this is the new and hip way to write documentation.
You could just use single-line comments with //
. At least those should be fine whether they are evaluated in bulk or one by one. But this leaves your code open to some other related problems. For example,
var template = `
Awesome multi-line template string...
...or error?
`;
If you don't want to constantly worry if things will work in the shell (I know I don't), you can change the way you execute the script.
Instead of piping the file to mongo like mongo.exe < script.js
, run the mongo command with "script.js" as an argument: mongo.exe script.js
.
This will evaluate the code in "scripted" mode instead of the "interactive" one, so it will solve these problems. Some things need to change though for this to work. Helpers like use test;
won't work in the scripted mode, you'll need to change it to its JavaScript counterpart var db = getDB('test');
.
These differences are documented here.
Avoid use block comments /* */ in javascript. Use only Single line comments //.
Source: Douglas Crockford-JavaScript_ The Good Parts (2008)
JavaScript offers two forms of comments, block comments formed with /* */ and line-ending comments starting with // . Comments should be used liberally to improve the readability of your programs. Take care that the comments always accu- rately describe the code. Obsolete comments are worse than no comments.
The /* */ form of block comments came from a language called PL/I. PL/I chose those strange pairs as the symbols for comments because they were unlikely to occur in that language’s programs, except perhaps in string literals. In JavaScript, those pairs can also occur in regular expression literals, so block comments are not safe for commenting out blocks of code. For example:
/*
var rm_a = /a*/.match(s);
*/
causes a syntax error. So, it is recommended that /* */ comments be avoided and // comments be used instead. In this book, // will be used exclusively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With