Dumping An Object is Like Taking an X-Ray
an OOP noobie analogy
Lately I've had the privilege of helping a good friend of mine climb "Mt. OOP", and in the process have been able to refine a lot of my own knowledge. I've also discovered that I sometimes make too many assumptions when imparting understandings, and this short post is in regards to one of those items: Dumping Objects.
One thing I always urge my fellow developers to do is to form a solid expectation of what the results will be when the code they're writing is executed. Well, what I found out is that my friend (and the rest of his team who are just getting their feet wet using objects) were certain that dumping an object should allow them to see EVERYTHING inside of it. Consider the following CFC:
Now, consider the following code which creates, initializes, populates, and dumps the "FleshAndBones" object:
The expectation was that when dumping an instance of the objBod object, "variables.stBody" should be visible somewhere in the dump. When it wasn't, red flags were raised and a revisiting of the CFC occurred until, by golly, the developer FORCED that variable to show up in the dump! How? By experimenting with scopes until he found one that allowed it to be visible: the THIS scope. Bad form, Jack. Putting variables into the THIS scope without a VERY good reason is tantamount to circumventing the very purpose of using an object, in my opinion. If you're going to do that you may as well just create a structure and manipulate that since the object will pretty much be behaving the same way. Enough on that, though.
Here is what the dump DOES contain:
To help explain what SHOULD be expected in the dump of an object, I gave my friend an analogy that helped him so much that he said I should definitely share it on my blog, so here it is:
CFDUMPing an object is exactly like taking an X-Ray of the object: You should expect ONLY to see the bones, not the soft innards. The bones of an object are its methods and metadata such as the method hints, return types, incoming arguments, etc. The soft innards are all of the variables, both private and public, that have been declared. It could also be any queries that have been executed, structures that were created, or anything else for that matter. Nothing besides the bones will ever be visible on an X-Ray, so not seeing those other internal items in the content of the dump is perfectly normal and is what SHOULD be expected.
Now, very often you WILL want to see what some of those soft innards of your object are looking like at various times. The answer to that is simply to make sure you have a method present whose job it is to return that particular soft innard, such as the following:
You can then dump that soft innard like so:
So in summary... CFDUMP (and the "getMetaData" function) give you X-Rays of an object. If you want to see the squishy parts, create a method that returns them!
Doug out.
One thing I always urge my fellow developers to do is to form a solid expectation of what the results will be when the code they're writing is executed. Well, what I found out is that my friend (and the rest of his team who are just getting their feet wet using objects) were certain that dumping an object should allow them to see EVERYTHING inside of it. Consider the following CFC:
<CFCOMPONENT DISPLAYNAME="FleshAndBones">
<CFFUNCTION NAME="init" ACCESS="public" RETURNTYPE="any" hint="I return the body with a single organ">
<CFARGUMENT NAME="initialOrgan" TYPE="string" REQUIRED="yes" hint="I am the first organ to be added to the body">
<CFSET variables.stBody = structNew() />
<cfset variables.stBody.organ1 = arguments.initialOrgan />
<CFRETURN THIS />
</CFFUNCTION>
<CFFUNCTION ACCESS="public" NAME="addOrgan" OUTPUT="false" RETURNTYPE="void" hint="I add a new organ to the body!">
<CFARGUMENT NAME="thisOrgan" TYPE="string" REQUIRED="yes" hint="I am the organ being added">
<cfset var newKey = "organ" & structcount(variables.stBody) + 1 />
<cfset variables.stBody[newKey] = arguments.thisOrgan />
</CFFUNCTION>
</CFCOMPONENT>
<CFFUNCTION NAME="init" ACCESS="public" RETURNTYPE="any" hint="I return the body with a single organ">
<CFARGUMENT NAME="initialOrgan" TYPE="string" REQUIRED="yes" hint="I am the first organ to be added to the body">
<CFSET variables.stBody = structNew() />
<cfset variables.stBody.organ1 = arguments.initialOrgan />
<CFRETURN THIS />
</CFFUNCTION>
<CFFUNCTION ACCESS="public" NAME="addOrgan" OUTPUT="false" RETURNTYPE="void" hint="I add a new organ to the body!">
<CFARGUMENT NAME="thisOrgan" TYPE="string" REQUIRED="yes" hint="I am the organ being added">
<cfset var newKey = "organ" & structcount(variables.stBody) + 1 />
<cfset variables.stBody[newKey] = arguments.thisOrgan />
</CFFUNCTION>
</CFCOMPONENT>
Now, consider the following code which creates, initializes, populates, and dumps the "FleshAndBones" object:
<cfset objBod = createobject("component","FleshAndBones").init(initialOrgan="Heart") />
<cfset objBod.addOrgan("Lungs") />
<cfset objBod.addOrgan("Pancreas") />
<cfdump var="#objBod#" />
<cfset objBod.addOrgan("Lungs") />
<cfset objBod.addOrgan("Pancreas") />
<cfdump var="#objBod#" />
The expectation was that when dumping an instance of the objBod object, "variables.stBody" should be visible somewhere in the dump. When it wasn't, red flags were raised and a revisiting of the CFC occurred until, by golly, the developer FORCED that variable to show up in the dump! How? By experimenting with scopes until he found one that allowed it to be visible: the THIS scope. Bad form, Jack. Putting variables into the THIS scope without a VERY good reason is tantamount to circumventing the very purpose of using an object, in my opinion. If you're going to do that you may as well just create a structure and manipulate that since the object will pretty much be behaving the same way. Enough on that, though.
Here is what the dump DOES contain:
To help explain what SHOULD be expected in the dump of an object, I gave my friend an analogy that helped him so much that he said I should definitely share it on my blog, so here it is:
CFDUMPing an object is exactly like taking an X-Ray of the object: You should expect ONLY to see the bones, not the soft innards. The bones of an object are its methods and metadata such as the method hints, return types, incoming arguments, etc. The soft innards are all of the variables, both private and public, that have been declared. It could also be any queries that have been executed, structures that were created, or anything else for that matter. Nothing besides the bones will ever be visible on an X-Ray, so not seeing those other internal items in the content of the dump is perfectly normal and is what SHOULD be expected.
Now, very often you WILL want to see what some of those soft innards of your object are looking like at various times. The answer to that is simply to make sure you have a method present whose job it is to return that particular soft innard, such as the following:
<CFFUNCTION ACCESS="public" NAME="getBody" OUTPUT="false" RETURNTYPE="struct" hint="I return the body!">
<cfreturn variables.stBody />
</CFFUNCTION>
<cfreturn variables.stBody />
</CFFUNCTION>
You can then dump that soft innard like so:
<cfdump var="#objBod.getBody()#" />
So in summary... CFDUMP (and the "getMetaData" function) give you X-Rays of an object. If you want to see the squishy parts, create a method that returns them!
Doug out.
Subscription Options
You are not logged in, so your subscription status for this entry is unknown. You can login or register here.
No comments found.

