0

I was browsing through the jade templating engine source code and I am trying to figure out what this statement means.

I get that it's going to try and instantiate options.compiler and if that fails instantiate Compiler, but the next part confuses me... Is this saying to call parser.parse and declare the returned value as a variable? If so, why is the rightmost paren around options?

var compiler = new (options.compiler || Compiler)(parser.parse(), options)
  , js = compiler.compile();

.
Here's some more context if that helps

function parse(str, options){
  try {
    // Parse
    var parser = new Parser(str, options.filename, options);

    // Compile
    var compiler = new (options.compiler || Compiler)(parser.parse(), options)
      , js = compiler.compile();

Github - Line 960

2
  • new (options.compiler || Compiler) must return a function that takes two parameters... Commented Jan 25, 2013 at 5:13
  • It's just the second argument for the constructor. Commented Jan 25, 2013 at 5:14

3 Answers 3

2

var compiler = new (options.compiler || Compiler) does not try to instantiate options.compiler. It looks for the existence of a compiler constructor as the property of option. If it doesn't find it, it uses Compiler as the constructor.

It then just passes those 2 arguments to the constructor being used: the first argument is the returned value of parser.parse(), and the second argument is options.


To simplify it, this can be rewritten as follows:

var theConstructor = options.compiler || Compiler;
var parsedStuff = parser.parse();
var compiler = new theConstructor(parsedStuff, options);
Sign up to request clarification or add additional context in comments.

Comments

1

Let's break it down.

(options.compiler || Compiler)

This expression seems to be designed to look for a "class" (well, technically a constructor function, this being JavaScript). The options object may be used to specify it, or else it will fall back to whatever is referenced by Compiler.

new (options.compiler || Compiler)(/* ... */)

Okay, now this makes more sense. We're invoking a constructor. It's just that the "class" was chosen dynamically.

new (options.compiler || Compiler)(parser.parse(), options)

When we income the constructor, we're passing in two parameters. The first is the result of calling the parse method of the parser object, and the second is the options object from earlier.

var compiler = new (options.compiler || Compiler)(parser.parse(), options)

That unholy mess is stored in the compiler variable.

var compiler = new (options.compiler || Compiler)(parser.parse(), options), js = compiler.compile();

You can declare and assign multiple variables in the same var statement, so that confuses things further. But the last part is pretty easy to understand by itself.

That statement could, and probably should, be broken down into multiple lines... but it is what it is.

Comments

0

It looks funny because the constructor to call is itself an expression.

And no, it isn't quite computing parser.parse() as the value of the declared local compiler, but rather it's creating a new object from the one returned and initializing compiler from that.

And, that rightmost paren is just because the code is aware that whatever constructor is returned ... it's going to want two parameters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.