How can I tell the Closure Compiler not to rename an inner function using SIMPLE_OPTIMIZATIONS? - google-closure-compiler

How can I tell the Closure Compiler not to rename an inner function? E.g., given this code:
function aMeaninglessName() {
function someMeaningfulName() {
}
return someMeaningfulName;
}
...I'm fine with Closure renaming the outer function (I actively want it to, to save space), but I want the function name someMeaningfulName left alone (so that the name shown in call stacks for it is "someMeaningfulName", not "a" or whatever). This despite the fact that the code calling it will be doing so via the reference returned by the factory function, not by the name in the code. E.g., this is purely for debugging support.
Note that I want the function to have that actual name, not be anonymous and assigned to some property using that name, so for instance this is not a duplicate of this other question.
This somewhat obscure use case doesn't seem to be covered by either the externs or exports functionality. (I was kind of hoping there'd be some annotation I could throw at it.) But I'm no Closure Compiler guru, I'm hoping some of you are. Naturally, if there's just no way to do that, that's an acceptable answer.
(The use case is a library that creates functions in response to calls into it. I want to provide a version of the library that's been pre-compressed by Closure with SIMPLE_OPTIMIZATIONS, but if someone is using that copy of the library with their own uncompressed code and single-stepping into the function in a debugger [or other similar operations], I want them to see the meaningful name. I could get around it with eval, or manually edit the compressed result [in fact, the context is sufficiently unique I could throw a sed script at it], but that's awkward and frankly takes us into "not worth bothering" territory, hence looking for a simple, low-maintenance way.)

There is no simple way to do this. You would have to create a custom subclass of the CodingConvention class to indicate that your methods are "local" externs (support for this was added to handle the Prototype library). It is possible that InlineVariables, InlineFunctions, or RemoveUsedVariables will still try to remove the name and would also need to be fixed up.
Another approach is to use the source maps to remap the stack traces to the original source.

read the following section
https://developers.google.com/closure/compiler/docs/api-tutorial3#export
Two options basically, use object['functionName'] = obj.functionName or the better way
use exportSymbol and exportProperty both on the goog object, here is the docs link for that
http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html
-- edit
ah, i see now, my first answer is not so great for you. The compiler has some interesting flags, the one which might interest you is DEBUG, which you can pass variables into the compiler which will allow you to drop some debugging annotations in via logging or just a string which does nothing since you are using simple mode.
so if you are using closure you can debug against a development version which is just a page built with dependiencies resolved. we also the drop the following in our code
if(DEBUG){
logger.info('pack.age.info.prototype.func');
}

Related

Is there a way to pass arguments in a custom Excel 4.0 function?

First of all, don't bother answering "just use a newer version of Excel", I must use 4.0 for what I want to do, thanks.
.
Now, the question is simple (even if the answer may not be):
You can pass arguments in proper Excel functions (ex: =OPEN("foo.xls";3), opening foo.xls and updating all references without a prompt).
You can make custom functions (well, you can name ranges to call with parenthesis, ex: =CUSTOM_FUNCTION() and it will call that function until it hits return).
You can return values to the original function to use with =RETURN(foo).
.
Is it possible to have a custom function with custom arguments that you can call without storing them in cells, ex: you call =ADD_TWO_NUMBERS(1;2) calling ADD_TWO_NUMBERS(X;Y) (or whatever it needs to be for it to work) then =RETURN(x+y) returns 3 (obviously a stupid example, but just to explain my case).
I've tried to search for it, but I haven't found anything so far.

Why recommend use ctx as the first parameter?

As the documentation said
Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter, typically named ctx
but I found, in the typical http request handle function, a http.Request object has .Context() method can retrieve the context which http request associate with.
So why recommend to use context as the first parameter in these functions? Is that reasonable in this situation?
I know that is not an absolute rule. But I want to know why the HandlerFunc is func(ResponseWriter, *Request) instead of func(context.Context, ResponseWriter, *Request).
Apparently HandlerFunc breaks this recommendation.
As described in the documentation you quoted above, ctx should be a (very) common argument for many functions. This is similar to the way many functions return an error. The best place for a common argument/return value is either as the first, or last in a list. (Arguably, Go could have chosen to make error always be the first return value--I won't discuss that here).
Since variadic variables may only be the last in the list of function arguments, this leaves the only option for a common argument to be the first one.
I expect this is why ctx is always first.
This pattern is often seen with other variables in Go (and other languages) as well. Any time a common variable is used by a set of related functions, that common variable often comes first in the argument list (or possibly second, after ctx).
Contrary to the advice you quoted, there are libraries that store ctx in a struct, rather than passing it around as the first argument. These are usually (always?) libraries which had to be retro-fitted to use ctx, long after the library contract was set in stone (by the Go 1.x compatibility guarantee).
Generally, you should follow the advice to pass ctx as the first argument, for any new work.

Overriding non-visible S3 method within namespace

First I have a package called DataBaseLayer and it has an S3 method called LoadFromTable(data_request). Second there is another package called RiskCalculator which determines several types of risks and does requests to the database by means of the package DataBaseLayer. Before "triggering" RiskCalculator (by means of an execute function defined in it) a connection to some schema of the database is set up and the method LoadFromTable will refer to that particular schema.
For some tests that I need to perform I have to switch schema depending on the value in data_request that enters LoadFromTable(data_request). Thus what I actually need is to insert a little check in LoadFromTable. As a note, currently there is only a default method implemented, i.e. LoadFromTable.default, and it would thus suffice even to only insert that check in that specific method.
My question is thus twofold:
1. Is there a general way to insert a piece of code before any LoadFromTable method is called, naively said: to insert a piece of code just before UseMethod("LoadFromTable", data_request) is "called".
2. If there is no such way, can we at least insert a piece of code just before LoadFromTable.default is called (for in my case that would now suffice).
As a final note, I can imagine you might say that the whole structure should be changed, and I agree, however, that is not an option for I am not the owner of these packages.
Thanks for your help.
It’s strongly discouraged, and fundamentally the wrong approach, to change code in loaded packages, so I won’t discuss it here (but I’ll mention that this is done via the assignInNamespace function).
But your case can be solved much easier: just override the LoadFromTable generic function in the RiskCalculator package as follows:
LoadFromTable = function (request) {
# TODO: perform your check here.
DataBaseLayer::LoadFromTable(request)
}
Now if you load your RiskCalculator package and call the function either explicitly (via RiskCalculator::LoadFromTable) or implicitly (via LoadFromTable after attaching the RiskCalculator package), your implementation will be called.
Try trace:
library(DataBaseLayer)
trace(LoadFromTable, quote(print("Hello")))
The library statement is important, even if you don't otherwise access that package yourself.

How do I change Closure Compiler compile options not exported to command line?

I found that some options in CompilerOption are not exported to the command line.
For example, alias all strings is available in the Closure Compiler's Java API CompilerOption but I have no idea how set this in the command line.
I know I can create a new java class, like:
Compiler c = new Compiler();
ComppilerOptions opt = new ComppilerOptions();
opt.setAliasAllString(true);
c.compile(.....);
However I have to handle the command line args myself.
Any simple idea?
============================
In order to try the alias all string option, I write a simple command line application based on compiler.jar.
However I found that, the result I got when open the alias all string is not what I expected.
For example:
a["prototype"]["say"]=function(){
var a="something string";
}
Given the above code, the something string will be replaced by a variable like this:
var xx="something string";
....
var a=xx;
....
This is fine, but how about the string "say"? How does the closure compiler know this should be aliased(replace it use variable) or exported(export this method)?
This is the compiled code now:
a.prototype.say=function(){....}
It seems that it export it.
While I want this:
var a="prototype",b="say",c="something string";
xx[a][b]=function(){.....}
In fact, this is the google_map-like compilation.
Is this possible?
Not all options are available from the command line - this includes aliasAllStrings. For some of them you have the following options:
Build a custom version of the compiler
Use the Java API (see example).
Use plovr
Getting the same level of compression and obfuscation as the Maps API requires code written specifically for the compiler. When properly written, you'll see property and namespace collapsing, prototype aliasing and a whole host of others. For an example of the style of code that will optimize that way, take a look at the Closure Library.
Modifying http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilationLevel.java?r=706 is usually easy enough if you just want to play with something.
Plovr (a Closure build tool) provides an option called experimental-compiler-options, which is documented as follows:
The Closure Compiler contains many options that are only available programmatically in Java. Many of these options are experimental or not finalized, so they may not be a permanent part of the API. Nevertheless, many of them will be useful to you today, so plovr attempts to expose these the experimental-compiler-options option. Under the hood, it uses reflection in Java, so it is fairly hacky, but in practice, it is a convenient way to experiment with Closure Compiler options without writing Java code.

VBScipt: Call builtin functions shadowed by global variables

VBScript on ASP Classic contains an "int" function. (It rounds numbers towards -∞.) Suppose that some excessively "clever" coder has created a global variable named "int". Is there any way to get at the original function? I've tried all manner of workarounds with scoping and dodgy execs, but no dice. I suspect that it is impossible, but I'm hoping that someone will know more about it than I do.
EDIT: Thanks for the responses. Since y'all asked, the global variable, called "Int" (though unfortunately, vbscript is not case-sensitive), is a factory for a class similar to Java's Integer. The default property is essentially a one-arg constructor; i.e. "Int(42)" yields a new IntClass object holding 42. The default property of IntClass in turn simply returns the raw number.
The creator was trying to work around the lack of proper namespaces and static methods, and the solution's actually pretty seamless. Pass in an IntClass where an int is expected and it will automatically trigger the default property. I'm trying to patch the last remaining seam: that external code calling "int" will not round properly (because the constructor uses CLng).
Not that I know of, getref only works on custom functions not on build-ins. I would suggest renaming the custom'int' function and update all references to this custom ones. You can use the search function visual studio (express) or any other tool of your liking for this. Shouldn't be to much work.
I didn't think reserved words would be allowed for function names or variables.
Duncanson's right. Do the pain and rename int. Chances are there are worse things going on than just this.
(why would someone make a global variable named int... that's going to take some thinking)
Or you can use CInt instead on Int
response.write trim(cint(3.14)) + "<br>"
Wrong!!
See NobodyMan comments

Resources