Monday, January 17, 2005

Display private variables in ColdFusion components

One thing that can be challenging is not being able to see private variables with cfdump when your are debugging your application. Cfdump only shows information about public properties and methods (variables in the "this" scope). Any private properties are not displayed.

In order to support stronger component encapsulation, I use private properties for most object properties. If I find that as an application develops, I always need to add or change some of the funtionality in some components. If the properties are private, I generally don't need to change much of the code that makes use of the components. If you use public properties, changing the name of one of the properties almost always means you've just broken some code that relies on your component.

But the issue remains: It's harder to debug your application if you keep most of your properties private. You can't use the cfdump tag effectively since it won't display any information about an object's private properties.

Here is a little trick I've been using that helps this situation. It's not perfect, but it's better than nothing.

Put this method in your cfcs to provide some insight into your application:


<cffunction name="showPrivate" access="public" returntype="void" output="true">
<cfset metadata = getMetaData(this)>
<cfset privateVariables = structNew()>
<cfloop index="i" from="1" to="#arrayLen(metadata.properties)#">
<cfset structInsert(privateVariables, metadata.properties[i].name, evaluate(metadata.properties[i].name))>
</cfloop>
<div style="position:absolute;top:10px;left:1100px; z-index:500;">
<cfdump var="#privateVariables#">
</div>
</cffunction>


In order for this to work, you have to make cfproperty entries for each private property you want to see in the declarations section of your component. In addition to supporting your debugging, you get entries made to support the cfcomponent browser.

To use this method, you do something like this:

<cfoutput>#myObject.showPrivate()#>

If your object is using composition, the complex values will display like a normal cfdump. If you want to see the private variables of one of your sub objects, make sure you have a getter for the sub object and then you can do something like this:

<cfoutput>#myObject.getMySubObject().showPrivate()#>

This works easisest if you put the showPrivate method in a base component that your other components extend. Otherwise you have to add the same method to each component you want this functionality in (which kinda defeats the OOP process).

If I get a chance, I'll see if I can find a way to make this thing drill down into subcomponents. Of course if somebody else wants to finish it, I'd be happy to post your modifications here :).

No comments:

Post a Comment