In many languages that provide a full implementation of OO concepts, constructors are complicated beasts. In ColdFusion, they don't technically exist at all. So, we have to use a work-around. In some ways, this is too bad, but in other ways it makes our job much simpler and more straightforward. We have less to worry about and can work more effectively in a short period of time. This is why CF is becoming known as "the Java productivity layer."
In CFMX 6, we were encouraged to use the space inside the cfcomponent tag and outside the cffunction tags to create a constructor. This had the unfortunate limitation of prevent us from initializing an object with Instance data (instance data being that data which is hidden away inside an object). So, in CFMX 6.1 and 7, we've turned to a technique called Method Chaining to create a basic constructor-type method.
Publication.cfc is now invoked as our example:
You see the init() method just inside the cfcomponent tag? That method is our constructor. It takes one argument, the string pubName, and initializes our instance of publication.cfc. In order to create an instance of publication.cfc, we need the following code:
What does this do? CFMX interprets this just so:
1. Someone wants to set something to a variable called myPub.
2. That something is an object, a CFC called publication.cfc.
3. {CFMX scurries off to find publication.cfc in the search path, starting in the local directory.}
4. Found it, created the space in RAM, have a working object in myPub.
5. Now they want me to execute init("My Publication")... executing... here it is!
And when it's finished with all that we have a valid instance of our publication.cfc. Inside the CFC, the init method passed the data from the cfset call outside the CFC thru to the setName method, which copied the data into the object's variables scope, and then "cfreturn this" kicks off and sends the whole object back to the variable myPub.
That's what "cfreturn this" does... sends the initialized instance of the class "publication" back to the variable myPubs... ++very++ important for our CF "constructors." Without it, the init() method would execute, but there would be nothing set into myPub and we couldn't use the CFC very well at all.
The "variables scope" has several names in OO: instance data, private data, private data members, etc. In CF it's called any of those and/or the "variables scope." Every CF document has a variables scope... even pages. Since CFCs are "ColdFusion executables," their variables scope is private to the CFC. In other words, if you use "cfset variables["test"]" inside a CFC, no other page can get at that data. That's what getters and setters are for, they're portals to the data inside a CFC's variables scope.
This concept is called Encapsulation in OO, and it's the foundational concept in OO's propensity to create maintainable, reusable objects. Since everything is "wrapped" in getters and setters, all that matters is the method calls to your objects. We could adapt the examples in this series to use a database instead of simply passing strings around... and yet nothing would have to change except the contents of the methods. The objects don't care ++how++ we get the data, just that when they call getName() they expect a string value to be returned. So get would still get, set would still set... as long as a get method that should return a string continues to return a string our application structure protects the application itself from falling apart when a simple change is made.
So, now you see... constructors can configure a CFC, initializing it with data that makes it useful, and they can be used to keep variables-scope data from going anywhere but where it's supposed to be. The use of the variables scope, and another scope called "function-local" keeps our code thread-safe, efficient, and keeps memory leaks, undue resource hogging, and all sorts of other nasties out of our applications. We'll go over function-local in a later entry, so for now, we're about done.