Coldfusion local scope outside of a function? - coldfusion

What exactly is the local scope defined outside of a function?
Consider the following code:
<cfscript>
local.madVar2 = "Local scope variable";
function madness() {
var madVar = "madness variable";
madVar2 = "madness two variable";
writeOutput("local: <BR>");
writeDump(local);
writeOutput("========================================= <BR>");
writeOutput("local.madVar2: <BR>");
writeDump(local.madVar2);
writeOutput("<BR>========================================= <BR>");
writeOutput("madVar2: <BR>");
writeDump(madVar2);
writeOutput("<BR>========================================= <BR>");
writeOutput("variables.madVar2: <BR>");
writeDump(variables.madVar2);
writeOutput("<BR>========================================= <BR>");
}
</cfscript>
Changing the madVar2 assignment by adding the var keyword, like this:
function madness() {
var madVar = "madness variable";
var madVar2 = "madness two variable";
Will yield this output:

The Local scope is only defined within functions and should not be used outside of it.
Variables defined outside the functions, default to the variables scope.
//that way
myVar = 0;
//will be the same as
variables.myVar = 0;
When you refer to local.madVar2 variable, which was initialized outside the function you're essentially referring to the local.madVar2 in the variables scope i.e the variable madVar2 is stored inside a struct named local which is stored in the variables scope.
So essentially, with the proper scoping in place your code is treated as:
writeOutput("variables.local.madVar2: <BR>");
writeDump(variables.local.madVar2);
Try dumping the variables scope just after defining the variables inside the function as:
var madVar = "madness variable";
madVar2 = "madness two variable";
writeDump(variables);
.....
You will see how the variables fall into scopes.

Related

Python: passing local variable reference as string

I use an interactive interpreter for data analysis, so I tend to just define functions and call them when I need them. In this case, I would like to call some function:
def function(var):
do stuff
ax.plot(x, y)
blah
ax.set_title('var')
where var in the function call is ndarray and var in set_title is the reference of the ndarray.
I'm currently implementing this with
def function(var, varstring):
do stuff
ax.plot(x, y)
blah
ax.set_title(varstring)
where var is foo and varstring is just 'foo' - an example call:
module.function(foo, 'foo')
now, my function takes many more variables and it's unwieldy to duplicate everything over and over again, but I can't figure out how to just get var as 'var' .. any attempt to do so provides me with a string of the ndarray values.
If you're working in the interpreter, the variables are likely in the global scope. Thus, you can access them using var = globals()[varstring] and then pass in the string name into each function.
Note that an object (var) has no knowledge of its names (varstring) which is why the global name needs to be passed to the function rather than the object itself.
you have to define your function in this way:
def function(varstring):
var = globals()[varstring]
# do stuff with `var` variable
ax.plot(x, y)
ax.set_title(varstring)
and then call module.function('foo')

Accessing module's local var

For testing reasons, is there a way to access a module's local variable?
module m {
var i = 0;
export function go() {
++i;
}
}
m.go();
expect(m["i"]).toBe(1); // m["i"] is undefined
[That is - is it possible to access a javascript function's local var?]
Ofcourse I can export it, or make it static and wrap it in a class, but I'm looking for something cleaner.
No, looking at the generated JavaScript helps in these situations:
var m;
(function (m) {
var i = 0;
function go() {
++i;
}
m.go = go;
})(m || (m = {}));
As you can see, var i is scoped within the function and therefore inaccessible outside that function.
Just follow your suggestion:
Of course I can export it, or make it static and wrap it in a class

how to put index variable in for ... in loop in local scope?

Whenever I use a for ... in loop, the index variable of the loop always seems to be in the variables scope.
For example if I have a component with a method that uses this loop:
for(key in params){
writeOutput(key);
}
The variable 'key' will be placed in the variables scope. If I already have declared a variables.key anywhere in the component, this value gets overwritten when I use this for ... in loop. What I actually need is something like this:
for(var key in params){
writeOutput(key);
}
This however throws a parsing error.
Is there any way to put the for ... in index in a different scope then the variables scope?
The default scope inside CFCs is variables if you don't var beforehand.
You have to var the index outside the loop like so:-
var key = "";
for(key in params){
writeOutput(key);
}
An alternative approach, to avoid varring everything within your functions, is to declare your variables within a "local" structure. In CF9 a local scope is built in but for CF8 or below do something like this:-
var local = structNew();
for(local.key in params){
writeOutput(local.key);
}
This syntax will work in ColdFusion 9 and higher:
for ( var key in params ){
writeOutput( key );
}

node.js: any way to export ALL functions in a file en masse (e.g., to enable unit testing), vs. one by one

in node.js, is there any shortcut to export ALL functions in a given file? i want to do this for unit testing purposes, as my unit tests are in a separate file from my production code.
I know i can go through and export each function manually, as in:
exports.myFunction = myFunction;
But i'm wondering if there is a simpler/slicker way to do this.
(and yes, i realize for modularity reasons it isn't always a good idea to export all functions, but for unit testing purposes you do want to see all the little functions so you can test them piece by piece.)
Thanks!
You could do something like this:
// save this into a variable, so it can be used reliably in other contexts
var self = this;
// the scope of the file is the `exports` object, so `this === self === exports`
self.fnName = function () { ... }
// call it the same way
self.fnName();
Or this:
// You can declare your exported functions here
var file = module.exports = {
fn1: function () {
// do stuff...
},
fn2: function () {
// do stuff...
}
}
// and use them like this in the file as well
file.fn1();
Or this:
// each function is declared like this. Have to watch for typeos, as we're typing fnName twice
fnName = exports.fnName = function () { ... }
// now you can use them as file-scoped functions, rather than as properties of an object
fnName();
Mixin objects is the answer.
This lib can help you: https://github.com/shimondoodkin/nodejs-clone-extend
//file1.js
var _ = require('cloneextend');
_.extend(this, require('file2.js'));
file1.js has now all exports from file2.js
Here's a simple way to do it. Parse the AST and look for top level function definitions, and export those.
const esprima = require('esprima')
const program = fs.readFileSync(__filename,'utf8')
const parsed = esprima.parseScript(program)
for (let fn of parsed.body) {
if (fn.type.endsWith('FunctionDeclaration')) {
module.exports[fn.id.name] = eval(fn.id.name)
}
}

Passing a struct to a function results in nested struct

When I pass a struct to a function that is expecting a struct, the function is nested inside another struct.
For example:
function getAnswerFromSO(struct question=StructNew()) {
writeDump(arguments.question);
}
CallinggetAnswerFromSO(question=myStruct); results in
question {
myStruct = {
text = 'foo',
subj = 'bar',
user = 1 }
};
** Obviously, this is not what a cfdump output looks like, but it illustrates the issue just the same.
Is there a way to prevent this nesting?
I can confirm that Ray's example works on CF9 as well.