Aug 18
One of my young padawans is learning the ways of ColdFusion and we’re now exploring the power of objects and what they can do for us. I’d given him an example object with an INIT method that looked like;
<cffunction name=“init” access=“public” returntype=“myobject” output=“false”>
<cfargument name=“params” type=“struct” required=“yes”
<cfset instance.dsn = params.dsn>
<cfreturn this>
</cffunction>
<cfargument name=“params” type=“struct” required=“yes”
<cfset instance.dsn = params.dsn>
<cfreturn this>
</cffunction>
being a good and keen padawan he questioned what it did…It’s a simple enough question but I couldn’t come up with an easily understood explanation….uh, err - it returns a copy of the CFC with variables personal to the CFC stored within the CFC for other methods to call perhaps? Any takers?
August 18th, 2005 at 8:25 am
I would say something like "it returns a reference to itself so that calling code can assign a variable to the CFC instance". I’ve actaully just explained that it "returns itself", which native constructors do automatically in other lanaguages and you must do manually in CFML.
August 18th, 2005 at 9:59 am
It returns the object with all it’s internal variables and functions.. actually the same as this would do.
<cfscript>
init = createobject("component","thecomponent");
<cfscript>
August 18th, 2005 at 3:09 pm
It doesn’t return a *copy* of the object (be careful there!), it returns (a reference to) the object itself.
Dave is pretty much spot on. I also tend to say "It returns the object itself" so that code can say:
obj = createObject("component","Thing").init(42);
I explain that createObject() merely creates an empty object (yeah, it runs the pseudo-constructor but I generally steer clear of that anyway!) whereas init() populates it with valid data.
If you want to go further into logistics…
If you did this:
obj = createObject("component","Thing");
obj.init(42);
then ‘obj’ would be an uninitialized object after the first statement. That might matter when ‘obj’ is really ’session.obj’ or ‘application.obj’ because another thread might try to access the uninitialized object. Of course this gets into the whole multi-threading / locking debate but using the chained create-init idiom means you don’t need to lock reads on shared objects because the variable is simply replaced by a new, fully-initialized version. The second form would require locks on every read because the variable has no atomic integrity (i.e., it can exist in an invalid state).
August 18th, 2005 at 3:40 pm
True very true.. forgot that one.. txns!! nice of you to use the almight number 42 in your example
August 19th, 2005 at 8:36 am
My answer would be "ColdFusion is stupid. You’ll occaisionally encounter quirks like this." The init method is our best answer to "constructors" from Java (and most other OO languages). If you take him to another language and teach him about constructors, the init() method might make more sense.
August 19th, 2005 at 1:17 pm
If he’s brand new to OOP in general, I’d probably turn it into a "real world" example. Make the class "automobile.cfc". Now there’s not just ONE automobile for the entire world, is there? No, so we need to create a new *instance* of "automobile", and then describe that particular instance - size, color, etc. CFreturn, returns my *instance* of the class, so i can do what I need to.
Also, in code examples I would stay away from things like naming variables "init" (per one of the other comments) if you also have a method called "init"…it will just add confusion; each thing should have a specific name:
automobile_instance = createObject( "component", "automobile" ).init()
…i think that makes the example a bit easier to follow.
hth
August 21st, 2005 at 3:06 am
The way I like to illustrate the concept, especially for someone who isn’t familiar with OO programming, is to call a function that returns "this" and then use cfdump to display the returned object. I have found that once someone "sees" the object representation on the screen, things become clear rather quickly.
Your student will see the object dumped on the screen and will hopefully understand that your object has power- it can return computed values - obj.returnComputedValue() - or other objects, rather than just properties like obj.X.
January 10th, 2007 at 11:44 am
I have same stupid question about "THIS". lets say the init() takes 3 arguments 2 Query(q1,q2) & other numeric(n1) . When I return this by saying <cfreturn this />
what will be the content of this? By running the code, I always see that "this" returns "q2" as result (the last query argument in the CFFUNCTION). But my question is WHY?
January 10th, 2007 at 5:43 pm
Tanvir, cfreturn this should not be returning the query unless you’re doing something wrong in your code! cfreturn this will return a reference to the entire CFC, i.e., it’s "this object", the one you just called init() on.
January 12th, 2007 at 2:53 pm
Sean,
Yes you are correct. I did something extremely wrong. Thanks again for responding.
T