Cool (and undocumented) ColdFusion 9 Feature

This post is more than 2 years old.

This didn't quite make the docs, nor do I think it was mentioned at CFUNITED, but one of the more interesting functions added to ColdFusion 9 is getFunctionCalledName. This returns the name of the calling function. Here is a somewhat useless example:

<cfscript> function foobar() { return getFunctionCalledName(); } </cfscript>

<cfoutput>#foobar()#</cfoutput>

This returns foobar, since the result of getFunctionCalledName is the name of the currently executing method. A slightly more sensible example, created by Elliott Sprehn, is the following:

component { variables.x = 1; variables.y = 2;

function init() { return this; }

function get() { var name = getFunctionCalledName(); return variables[mid(name,4,len(name))]; }

function set(value) { var name = getFunctionCalledName(); variables[mid(name,4,len(name))] = value; }

this.getX = get; this.getY = get; this.setX = set; this.setY = set; }

Notice a few things in play here. He created one generic get and set function and then made copies of them for getX/getY and setX/setY. The generic functions work by using the getFunctionCalledName to figure out the real name of the function and update the appropriate value. As an example:

<cfset es = new es()> <cfdump var="#es#"> <cfset es.setX("foo")> <cfoutput>#es.getX()#</cfoutput>

So can folks think of any interesting uses for this?

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Micah posted on 8/19/2009 at 6:02 AM

Very cool. I've been looking for this feature to use with bug alerts. Ideally I'd like to automatically specify which function and class or file in which an issue occurred. Does any one have any idea how to do this in CF8 (perhaps with java)?

Comment 2 by Jody Fitzpatrick posted on 8/19/2009 at 7:11 AM

This gets me thinking perhabs this could be used in
error handling. Where you would be able to see the precise function that through you the error. Hmmm might
have to code something here.

Comment 3 by Joshua Curtiss posted on 8/19/2009 at 11:02 AM

Whoah, it's like what we sometimes try to do with onMissingMethod(), but more elegant because we won't need one big if..then..else block for the different types of dynamic methods we want to implement.

Plus, the method names can still be dynamically generated, say, in the init() method! (I'm assuming this, haven't test it)

Comment 4 by Gary Gilbert posted on 8/19/2009 at 12:28 PM

Interesting that they added this. I posted something similar to this back in February of last year http://www.garyrgilbert.com...

An Adobe forums user wanted to know how to find out what function called his function, or method. Back then with cf8 the only way was to force and catch an error to get the stack trace, and parse out the function name. A total hack, now I see they have provided a function to do that for you. Pretty cool.

Comment 5 by Gary Gilbert posted on 8/19/2009 at 12:42 PM

Actually just read entire post again, first pass I misunderstood the function call.... so my post in february of last year is similar in that its totally different...

sigh I need another coffee so that I am really awake

Comment 6 by Martijn van der Woud posted on 8/19/2009 at 1:17 PM

From a design perspective, one could argue that this function should be used with caution, because it violates the so-called 'Hollywood principle' (don't call us, we will call you). Usually it is best when a method just does it's own thing, oblivious of the object and/or method that is calling it. Otherwise the behavior of the method might be dependent of some characteristics of the caller, causing tight coupling which may reduce maintainability; the method than has two potential reasons to change:

1) because it's own logic must be changed
2) because something changed in one or more callers

Ideally methods and/or object have only one potential reason for change.

Besides this caveat, this function allows for even more flexibility, which in my opinion is the number one advantage of CFML over other languages like Java. I wonder what people can come up with now that they know about this...

Comment 7 by tony petruzzi posted on 8/19/2009 at 4:07 PM

@Micah,

you can kind of do this in cf8, however it's extremely hackish. basically what you can do is create a java.lang.Execption and then parse out the information from the exceptions tagcontext. if you want to see it in the real world, have a look at the CFWheels source code for the $deprecated().

http://code.google.com/p/cf...

We're using this technique to announce deprecated elements of the framework to developers and giving them a heads up that these elements could be removed in a future release.

Comment 8 by Ben Nadel posted on 8/19/2009 at 5:52 PM

Interesting function. It would be cool if they could also provide a method to get the reference to the function object itself as well. I like your example with the generic getter/setters.

Comment 9 by Raymond Camden posted on 8/19/2009 at 6:09 PM

@Ben: That example was from Elliott Sprehn - super smart CF guy. :)

Comment 10 by Ben Nadel posted on 8/19/2009 at 6:11 PM

@Ray,

No doubt Elliott is wicked smart (too bad he wasn't at CFUNITED this year - I hear he had an internship at Microsoft). His example is cool, but breaks if the target method is not stored in the variables scope.

Comment 11 by Raymond Camden posted on 8/19/2009 at 6:13 PM

How would the method _not_ be stored in the variables scope?

Comment 12 by Ben Nadel posted on 8/19/2009 at 6:16 PM

If you store a pointer to it in the request scope or something. I am not talking about methods inside a CFC, but free-floating functions (which can be pulled out of a CFC as well).

Comment 13 by Raymond Camden posted on 8/19/2009 at 6:19 PM

Ah, interesting - now I get what you mean.

Comment 14 by Ben Nadel posted on 8/19/2009 at 6:21 PM

It originally came up because I wanted to be able write a UDF to the ram disk and then read it back in and have it be able to reference itself.

Comment 15 by Ron Hopper posted on 8/19/2009 at 6:22 PM

That's great! I needed this function for partial-mocking in cfSpec. When running a test, you can dynamically inject code to stub out methods on other objects so they are not actually called during the test. I've done it by pointing method names at onMissingMethod, but that's messy and only works when the function is called externally or with an explicit 'this' scope. Great news! Thanks for posting it.

Comment 16 by Hemant posted on 8/21/2009 at 8:26 AM

I guess I should add this to my presentation for MAX. Thanks Ray for your post highlighting this function.

Comment 17 by Eric Twilegar posted on 9/8/2009 at 6:55 PM

I'll probably use this in my views/templates.

We had a system setup where at the begging and end of functiosn we'd output a something like "Drawing start of table"...and then something similiar at the end the end. Of course the function only outputted when in debug mode.

At the end of the day you could throw a page into debug mode and easily find where in a template something was rendered. We tend to put lots of functions in our templates to better encapsulate them as they start to get really long.

This could help the developer find exactly what code is drawing a portion of the page. Hopefully it's return the CFC, CFM or whatever else might be useful.