I was recently working on a project where I needed to call a getter dynamically. If your not quite sure what I am talking about that is perfectly fine because we are going to walk through it. I needed the ability to get all of the properties of any component passed to me, then loop those properties and one by one get the values of that property by calling the getter method on that property. Another reason for this post is because I found 2 different ways to accomplish this based on how you do it. With that I want to walk through some cocde that shows both methods.
The first method achieving our goal is if we are trying to access the values outside of our component. What I mean by that is if we were to create in instance of our class and then loop over the properties how could we get those values. It turns out it was pretty easy to do just that. First we need to take a look at our very basic user object. With our component in place we can create an instance of it and set our property values by calling each set method. Next we need a way of dynamically grabbing a list of all the properties in the component. We can accomplish this by grabbing the components meta data. Finally we loop over the array of properties and print the key and value. To dnamically call the getter you can use the evaluate method. This is easier if you are using tags because you can just use cfinvoke. I don't know, maybe it's just me but neither seem like the "right" way to do it but it works!
The next method is going to be within our component. Maybe we want to create a method that would return each key/value for all the properties in our component. We could write each one of them out but I like writing less code so I have an example of how to do that as well. The only differences here is we are doing all the work internally to automatically expose this feature to the caller. You will notice though that we are not using the evaluate method here. We can simply call our getter by referring to this and using a dynamic name. This is an example of getting the values from the component above.
The weird thing is if you try and use the same method of calling the getter outside of the component it just does not work. The code above will not work, it just returns nothing for each.
With the new script upgrades in ColdFusion 9 I imagine people will be running into issues like this so I thought I would share this with you. If anyone knows why I can't use that same syntax outside of the component I would love to hear it. It's always better to understand why you can't do something instead of just accepting the fact that you can't!

#1 by Sean Corfield on 10/7/09 - 4:41 PM
evaluate( "obj.get#key#()" )
One of the very few cases where evaluate is useful (and cleaner than the alternative).
#2 by Dan Vega on 10/7/09 - 4:43 PM
#3 by Gareth on 10/8/09 - 11:30 AM
I found that it's easy enough to set a pointer variable to a component's function.
You can execute that pointer function within the cfc, and it will have access to the cfc's scope.
However, if you execute the pointer function outside the cfc, it can't access the cfc's scope. So any references to the variables scope inside the function will fail.
I ended up using cfinvoke, but would have preferred a cfscript alternative.
It does seem to be something missing from cfscript
#4 by Dan Vega on 10/8/09 - 2:01 PM
#5 by Gareth on 10/21/09 - 11:09 AM
I've always been told evaluate() was bad for performance, so tried to avoid it where possible.
However, I've no idea why it should be any slower than using cfinvoke dynamically. Have you found any noticeable performance problems?
#6 by Aaron Greenlee on 10/12/10 - 6:02 PM
After...
method = user["get#property.name#"];
Reset the method using a safe name.
user.fn = method;
Now, you call user.fn() and you can get the value. From my test this evening, it appears the function looses its access to the scopes that contain the value one expects and the function returns 'undefined' when called on it's own. Inserting the function into the
user object allows the function to again access it's scopes and returns the data we expected.
Thanks,
Aaron
Your code '