Sean asks:
Do you know of a function, either built in or user defined, that will display the scope where a variable exists. I'm working with old code that does not always scope the variables and I'm having a hard time tracking some of them down.
While I'm not aware of such a function, I'm sure we can write one easily enough. Here is what I came up with.
function findScope(v) {
var scopes = "arguments,variables,thread,cgi,cffile,url,form,cookie,client";
var s = "";
var ptr = "";
var i = 1;
for(;i < listLen(scopes); i++) {
s = listGetAt(scopes,i);
ptr = structGet(s);
if(structKeyExists(ptr, v)) return s;
}
return "";
}
This UDF works with a predefined list of scopes based on the scopes that ColdFusion will check when you do not define a scope. (More on this here.) This isn't an exact match to the list ColdFusion checks as some of them are unnamed. Also, you may want to extend this list to include Application and Session. Those scopes are not checked with unscoped variables, but if you want, just add them to the list.
Once we have our list, the rest of the code isn't too exciting. We loop over each scope and use structGet to get a pointer to the scoper. We then do a simple structKeyExists and if the key exists, we return the scope name. Here is a simple test script I wrote to demonstrate the UDF in action:
<cfset variables.x = 1>
<cfset url.y = 2>
<cfset form.z = 3>
<cfset cookie.a = 'peanut butter jelly'>
<cfoutput>
findScope('x')=#findScope('x')#<br />
findScope('y')=#findScope('y')#<br />
findScope('z')=#findScope('z')#<br />
findScope('a')=#findScope('a')#<br />
findScope('idontexist')=#findScope('idontexist')#
</cfoutput>
Note - this UDF will only work in ColdFusion 8 because of the < and ++. You can modify that easily enough. Frankly now that I've got these in cfscript under CF8 I'm going to use them everywhere I can! You would also need to remove the thread value from the list.