I understand without any problems how perl
's closures works, like the next one
use 5.012;
use strict;
use warnings;
sub countdown {
my $start = shift;
return sub { $start-- }
}
my $c10 = countdown(3);
say while( $_ = $c10->() );
I'm trying to understand the next piece of Javascript:
var runInSandbox = (function(js, inputPath) {
(function() {
if ((!context.initialized__QUERY)) {
return createContext();
};
})();
(function() {
if (typeof(inputPath) !== 'undefined') {
(process.argv)[1] = inputPath;;
(context)["__dirname"] = path.dirname(inputPath);;
return (module)["filename"] = inputPath;;
};
})();
return vm.runInContext(js, context, "sibilant");
});
NO CHANCE! :( PLEASE can someone rewrite the above to perl ? I know perl a bit - so for me will be extremely useful to understanding JS basics and the constructions like:
(...)() - more precisely
(function(){.....})()
double ((
in the if
if ((!context.initialized__QUERY)) {
or the next
(context)["__dirname"] = something ;;
or
return (module)["filename"] = inputPath;; // why double ;;?
And if someone coul'd suggest me any resource something like: Learning Javascript for perl programmers
- would be very nice ;)
Ps: the JS (shortened) is from here: https://github.com/jbr/sibilant/blob/master/lib/cli.js
I'm not extremely well-versed with Perl closures, so I will at least try to demystify this for you.
The form:
(function(...) {
...
})();
is a self-invoked anonymous function1. This means that you write out an anonymous function, and then invoke it immediately. This is usually done for encapsulation2. For example, if you end up creating a bunch of variables, but don't want it to pollute the global namespace, you can put it inside an anonymous, self-invoked function. However, in this case I don't see why the first invocation is necessary at all, since it's simply checking a flag or something. What is even stranger is the return
inside those self-invoked functions. They aren't being assigned to anything. I would hazard a guess that createContext()
initializes the context
variable, but that return
in there is effectively useless. The same goes for the following:
return (module)["filename"] = inputPath;;
As far as the double ((
and ))
, they seem to be largely unnecessary and so I'm not sure why the author originally put it in there. For example:
if ((!context.initialized__QUERY))
Isn't any different from:
if (!context.initialized__QUERY)
Also, the parentheses in the following are also unnecessary, as are the double semicolons:
(context)["__dirname"] = something ;;
Honestly, it just looks like poorly-written Javascript, or perhaps JavaScript that was autogenerated (this is most probably the case).
You could rewrite it like so:
var runInSandbox = function(js, inputPath) {
if (!context.initialized__QUERY) {
createContext();
};
if (typeof inputPath !== 'undefined') {
process.argv[1] = inputPath;
context["__dirname"] = path.dirname(inputPath);
module["filename"] = inputPath;
};
return vm.runInContext(js, context, "sibilant");
};
Notes:
sub { ... }->()
.{ my $var; ... }
instead of sub { my $var; ... }->()
and do { my $var; ...; EXPR }
instead of sub { my $var; ...; return EXPR; }->()
.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