Closure compiler mixes variable names - google-closure-compiler

I have a problem where the Closure Compiler renames a global variable something like x.sa.xa but in all function where that global variable is referenced the compiler renames it something else like H.sa.xa
When I view the HTML page I get a JavaScript TypeError: H.sa.xa is undefined.
// Top-level namespace for all the code
var nam = nam || {};
(function($, nam) {
goog.provide('nam.jsConfig');
nam.jsConfig.cookies = {"RECENT_ITEMS": "recentitems"};
})($, nam);
(function($, nam) {
goog.provide('nam.util.cookie');
nam.util.cookie.readMyCookie = function () {
var ritems_cookie = nam.util.cookie.JSONCookie.get(nam.jsConfig.cookies['RECENT_ITEMS']);
};
})($, nam);
Closure Compiled Code:
x.sa = {};
x.sa.xa = {RECENT_ITEMS:"recentitems"};
H.a = {};
H.a.cookie = {};
H.a.Tm = function() {
var a = H.a.cookie.ja.get(H.sa.xa.RECENT_ITEMS);
};
For some reason the Closure Compiler is referencing H.sa.xa.RECENT_ITEMS instead of x.sa.xa.RECENT_ITEMS
Any reason why the compiler is doing this this?

The only way I can interpret your question is that one of two things is happening:
There is an issue with the Closure Compiler's obfuscating and minimizing code, or
The error you are seeing is from JavaScript running outside of the code compiled by the Closure Compiler that is referencing a compiled variable directly.
If it is the former, you should isolate the case that is causing variable misalignment and submit it as a bug to Google. All of us using the Closure Compiler would greatly appreciate it.
If instead, as I suspect, it is the latter, you are most likely not exporting the global variable you wish to use outside of the compiled code. The easiest way to do this is to call goog.exportSymbol() function to make the global variable available outside of your code assembled by the Closure Compiler. For example, if you wished to access the property sandwich.meat.Ham in compiled mode from non-compiled code, you could do the following:
goog.exportSymbol('sandwich.meat.Ham', sandwich.meat.Ham);
Then you could have some code that exists outside of your compiled code that references the exported variable:
function() {
var meat = new sandwich.meat.Ham();
}

Let me guess what you are doing: compiling each file independently in ADVANCED mode. If so, this isn't how ADVANCED mode works. In advanced mode if you want to share variable and properties between compilations jobs you need to export them.

There are much more significant issues in the code example you provided. For one
goog.provide('nam.util.cookie');
was turned into
H.a = {};
H.a.cookie = {};
Yet later this code:
nam.util.cookie.readMyCookie = function () {...
was turned into
H.a.Tm = function() {...
Where one would expect it should be
H.a.cookie.Tm = function() {...
Additionally, the fact that you use nam as the base namespace for both halves of the uncompiled code and that it gets turned into separate x and H namespaces, respectively, also suggests more is at play. Some suggestions:
If you wish to use the module pattern, put the provide/require statements outside of the module
Don't manually create namespaces with stuff like var nam = nam || {} because provide does this for you already
As others have mentioned, both files containing nam.jsConfig and nam.util.cookie should be included in a single compilation
Make sure you goog.require('nam.jsConfig') in the file with nam.util.cookie.readMyCookie, to ensure the dependency requirements are met
FWIW, we use closure in an extensive application with hundreds of files, containing interdependencies like this. I would be highly suspect that the issue lies not with the tools, but instead with how they are being used.

Related

Finding a Module's path, using the Module object

What is the sane way to go from a Module object to a path to the file in which it was declared?
To be precise, I am looking for the file where the keyword module occurs.
The indirect method is to find the location of the automatically defined eval method in each module.
moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,)))
for example
moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,)))
using DataStructures
moduleloc(DataStructures)
Outputs:
/home/oxinabox/.julia/v0.6/DataStructures/src/DataStructures.jl
This indirect method works, but it feels like a bit of a kludge.
Have I missed some inbuilt function to do this?
I will remind answered that Modules are not the same thing as packages.
Consider the existence of submodules, or even modules that are being loaded via includeing some abolute path that is outside the package directory or loadpath.
Modules simply do not store the file location where they were defined. You can see that for yourself in their definition in C. Your only hope is to look through the bindings they hold.
Methods, on the other hand, do store their file location. And eval is the one function that is defined in every single module (although not baremodules). Slightly more correct might be:
moduleloc(mm::Module) = first(functionloc(mm.eval, (Any,)))
as that more precisely mirrors the auto-defined eval method.
If you aren't looking for a programmatic way of doing it you can use the methods function.
using DataFrames
locations = methods(DataFrames.readtable).ms
It's for all methods but it's hardly difficult to find the right one unless you have an enormous number of methods that differ only in small ways.
There is now pathof:
using DataStructures
pathof(DataStructures)
"/home/ederag/.julia/packages/DataStructures/59MD0/src/DataStructures.jl"
See also: pkgdir.
pkgdir(DataStructures)
"/home/ederag/.julia/packages/DataStructures/59MD0"
Tested with julia-1.7.3
require obviously needs to perform that operation. Looking into loading.jl, I found that finding the module path has changed a bit recently: in v0.6.0, there is a function
load_hook(prefix::String, name::String, ::Void)
which you can call "manually":
julia> Base.load_hook(Pkg.dir(), "DataFrames", nothing)
"/home/philipp/.julia/v0.6/DataFrames/src/DataFrames.jl"
However, this has changed to the better in the current master; there's now a function find_package, which we can copy:
macro return_if_file(path)
quote
path = $(esc(path))
isfile(path) && return path
end
end
function find_package(name::String)
endswith(name, ".jl") && (name = chop(name, 0, 3))
for dir in [Pkg.dir(); LOAD_PATH]
dir = abspath(dir)
#return_if_file joinpath(dir, "$name.jl")
#return_if_file joinpath(dir, "$name.jl", "src", "$name.jl")
#return_if_file joinpath(dir, name, "src", "$name.jl")
end
return nothing
end
and add a little helper:
find_package(m::Module) = find_package(string(module_name(m)))
Basically, this takes Pkg.dir() and looks in the "usual locations".
Additionally, chop in v0.6.0 doesn't take these additional arguments, which we can fix by adding
chop(s::AbstractString, m, n) = SubString(s, m, endof(s)-n)
Also, if you're not on Unix, you might want to care about the definitions of isfile_casesensitive above the linked code.
And if you're not so concerned about corner cases, maybe this is enough or can serve as a basis:
function modulepath(m::Module)
name = string(module_name(m))
Pkg.dir(name, "src", "$name.jl")
end
julia> Pkg.dir("DataStructures")
"/home/liso/.julia/v0.7/DataStructures"
Edit: I now realized that you want to use Module object!
julia> m = DataStructures
julia> Pkg.dir(repr(m))
"/home/liso/.julia/v0.7/DataStructures"
Edit2: I am not sure if you are trying to find path to module or to object defined in module (I hope that parsing path from next result is easy):
julia> repr(which(DataStructures.eval, (String,)))
"eval(x) in DataStructures at /home/liso/.julia/v0.7/DataStructures/src/DataStructures.jl:3"

How to call a dynamically named function in Railo

Suppose I have this struct:
myValue = {
value = 100,
formatter = "numberFormat",
formatMask = "0.0"
};
How can I call up the function specified in myValue.formatter? Such as this:
var valueString = myValue[ "formatter" ]( myValue.value, myValue.formatMask );
The write-ups on dynamically-named function tend to focus on component methods or custom defined functions, such as this. However, it doesn't seem to work with native functions. I am running Railo 4.2 btw.
Is there a way to dynamically call native functions? Or do I have to fall back to doing if/then statements (if "numberFormat" then return numberFormat(val,mask)) ?
Thanks!
numberFormat() is a built-in function, and CFML built-in functions are not "first class" so cannot be called like that: one cannot make a reference to a built-in function, which is necessary for this sort of thing to work.
You'll need to revise your approach here, possibly using evaluate(), or wrapping numberFormat() in your own UDF.

Is stricter error reporting available in R?

In PHP we can do error_reporting(E_ALL) or error_reporting(E_ALL|E_STRICT) to have warnings about suspicious code. In g++ you can supply -Wall (and other flags) to get more checking of your code. Is there some similar in R?
As a specific example, I was refactoring a block of code into some functions. In one of those functions I had this line:
if(nm %in% fields$non_numeric)...
Much later I realized that I had overlooked adding fields to the parameter list, but R did not complain about an undefined variable.
(Posting as an answer rather than a comment)
How about ?codetools::checkUsage (codetools is a built-in package) ... ?
This is not really an answer, I just can't resist showing how you could declare globals explicitly. #Ben Bolker should post his comment as the Answer.
To avoiding seeing globals, you can take a function "up" one environment -- it'll be able to see all the standard functions and such (mean, etc), but not anything you put in the global environment:
explicit.globals = function(f) {
name = deparse(substitute(f))
env = parent.frame()
enclos = parent.env(.GlobalEnv)
environment(f) = enclos
env[[name]] = f
}
Then getting a global is just retrieving it from .GlobalEnv:
global = function(n) {
name = deparse(substitute(n))
env = parent.frame()
env[[name]] = get(name, .GlobalEnv)
}
assign('global', global, env=baseenv())
And it would be used like
a = 2
b = 3
f = function() {
global(a)
a
b
}
explicit.globals(f)
And called like
> f()
Error in f() : object 'b' not found
I personally wouldn't go for this but if you're used to PHP it might make sense.
Summing up, there is really no correct answer: as Owen and gsk3 point out, R functions will use globals if a variable is not in the local scope. This may be desirable in some situations, so how could the "error" be pointed out?
checkUsage() does nothing that R's built-in error-checking does not (in this case). checkUsageEnv(.GlobalEnv) is a useful way to check a file of helper functions (and might be great as a pre-hook for svn or git; or as part of an automated build process).
I feel the best solution when refactoring is: at the very start to move all global code to a function (e.g. call it main()) and then the only global code would be to call that function. Do this first, then start extracting functions, etc.

Javascript: sync to async converter libs

1) What is better streamlinejs: https://github.com/Sage/streamlinejs
or narrative: http://www.neilmix.com/narrativejs/ ? any others libs?
2) How does any of those libraries even work?
(I read the docs, I am looking for a simplify explanation of what's going on behind the scene..)
As far as question #2....in general these things:
parse javascript into some abstract syntax tree (AST)
transform the AST
stringify the transformed tree back into javascript
I wrote a partial converter as a learning experience a while back. I used uglify.js to parse into an AST and then the tree walker that lib provides to do the transformations. The transformations were general purpose and produced code that looked like a state machine -- where each step started with a sequence of 0 or more sync actions and ended with an async action. E.g. this simple script:
var fs = require('fs');
console.log(fs.readFile('input.js', _).toString('utf-8'));
would get converted to this:
var fs, $v_0;
function s_0() {
fs = require("fs");
fs.readFile("input.js", function(err, res) {
if (err) s_err(err); else {
$v_0 = res;
s_1();
}
})
}
function s_1() {
console.log($v_0.toString("utf-8"));
}
s_0()
I imagine that streamline and the like do something very similar. Certain structures (loops, try/catch) need special handing but the general approach is the same -- convert into a state machine.
The issues with this approach that I found were:
1) it's not a local problem - i.e. any async behavior that needs to be handled infects everything all the way up the call stack.
2) you need function metadata so you either have to make assumptions or require people to annotate their functions in some manner.

How to do typeof of a module in a fsx file?

Let's say I have a Foo.fsx script that contains this code:
module Bar =
let foobar = "foo"+"bar"
open Bar
let a = System.Reflection.Assembly.GetExecutingAssembly()
let ty = a.GetType("Foo.Bar") // but it returns null here
How can I achieve that? Thanks!
This is a tricky question, because F# interactive compiles all types into types with some mangled names (and the executing assembly can contain multiple versions of the same type).
I managed to do it using a simple trick - you'd add an additional type to the module - then you can use typeof<..> to get information about this type. The type inside a module is compiled as a nested type, so you can get the name of the type representing the module from this (nested) type:
module Bar =
let foobar = "foo"+"bar"
type A = A
// Get type of 'Bar.A', the name will be something like "FSI_0001+Bar+A",
// so we remove the "+A" from the name and get "FSI_0001+Bar"
let aty = typeof<Bar.A>
let barName = aty.FullName.Substring(0, aty.FullName.Length - "+A".Length)
let barTy = aty.Assembly.GetType(barName)
// Get value of the 'foobar' property - this works!
barTy.GetProperty("foobar").GetValue(null, [| |])
You could probably simply search all types in the assembly looking for +Bar. That would work as well. The benefit of the trick above is that you get a reference to the specific version of the type (if you interactively run the code multiple times, you'll get a reference to the module corresponding to the current Bar.A type)
As a side-note, there were some discussions about supporting moduleof<Bar> (or something like that) in future versions of F# - this is a bit inelegant as it is not a real function/value like typeof, but it would very useful!

Resources