The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

Calling functions with a dynamic name

posted under category: ColdFusion on May 28, 2009 at 1:00 am by Nathan

For a while now, the CF community has been stumbling around the concept of calling a dynamic function. Well, as it turns out, ColdFusion is more functional that it may seem on the surface. Let's have some fun with what, at first, seems like a difficult problem.

Let's say we have a method that receives the name of another method as an argument: myStaticFunction("myDynamicFunction"). Now what? First, here's the methods (I haven't checked any of this, so let's call it pseudo-code.

function myDynamicFunction(){return true;}

function myStaticFunction(methodName) {
methodName(); // fails for calling a string like a function
variables[methodName](); // fails for a syntax error - []() = bad cfml!
// umm, now what?
}

So here we are in the same old spot. First, the old school method, the one easily turned to in time of need, the cfinvoke tag. Personally, I dislike the cfinvoke tag. It seems to take me out of my flow. It ruins my mojo. It's like longhand syntax for CF - it's somewhat of an oxymoron. Nevertheless, here's what you would do:

<!--- First, note that we have to rewrite it in tags. Not awful, but I dislike the switch. --->
<cffunction name="myStaticFunction">
<cfargument name="methodName" />
<cfset var methodResult = "" />
<cfinvoke method="#methodName#" returnvariable="methodResult" />
<cfreturn methodResult />
</cffunction>

This works, but there's got to be a better way! There has to be a less cheap way, something without all the #'s and stuff. And there is:

// back to cfscript, yay!
function myStaticFunction(methodName) {
var method = variables[methodName];
return method();
}

That's much more like it! Of course this assumes we're in a cfc or something, where the method is in the variables scope. Now, what other magical things can we do?

Well, I wasn't going to share this one until the next entry, but since you're talking me into it, here it is with onMissingMethod, dynamically calling a method with dynamic arguments. This onMissingMethod attempts to call a getter when you just call the property - in other words, user.name() will be automatically translated into user.getName(), to give you a nice jQuery type of syntax:

function onMissingMethod(missingMethodName, missingMethodArguments) {
var f = 0;
if (structKeyExists(variables, "get" & arguments.missingMethodName)) {
f = variables["get" & arguments.missingMethodName];
f(argumentCollection=arguments.missingMethodArguments);
} else {
// choke!
}
}