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 12: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!
    }
}