Advanced CFML 2: Objects and Classes Part II

Using the pseudo-constructor is not the most secure way of working with components, but it has its uses. A constructor’s purpose is to execute when an object is created (instantiated), and this is usually done inside a function/method in other object-oriented programming languages. The pseudo-constructor on the other hand was executed outside of any functions (but before the first function).

In CFML, we name our constructor “init”, which stands for initialize. But before we get into using the init() constructor, let’s do one more example using a pseudo-constructor, and then replace it with the init() constructor.

<cfcomponent displayname="city" output="false">
    <!--- Private Variable (pseudo-constructor) --->
    <cfset variables.cityName = "" />
    <!--- Setter Method --->
    <cffunction name="setName" output="false">
        <cfargument name="newName" type="string" />
        <cfset variables.cityName = arguments.newName />
    </cffunction>
    <!--- Getter Method --->
    <cffunction name="getName" output="false">
        <cfreturn variables.cityName />
    </cffunction>
</cfcomponent>

In this component we have a variable called “cityName” that is private. Each time we create an object of this component, this variable is initialized since it is before the first method (function). We then have two methods, one that sets the name of the variable through an argument it takes, and other returns (gets) the variable. These are called setter/getter methods, they are also called “mutators” in other object-oriented programming languages. The point of them are to set (modify) and get (return) data in an easier way so that when applications get bigger, additional functionality can be added more easily.

In our calling page, we could have this:

<cfset cityObject = CreateObject("component","com.city") />

<cfoutput>
    #cityObject.setName("New York City")#
    #cityObject.getName()#
</cfoutput>

Here we created an object called “cityObject”. And we accessed the “setName” method and passed an argument to it. To return the modified data we used our “getName” method.

Using the Init() Constructor

In the changed example below, we created a function and named it init (which is going to act as our constructor). Our function is going to take an argument named “cityName” and set a variable called cityName to that argument (which is also called cityName). All of this in then returned in the this scope. When using the init() method it is required that everything been returned in the this scope otherwise the methods in our component (setter/getter) will not be accessible.


<cfcomponent displayname="city" output="false">
    <!--- Constructor --->
    <cffunction name="init" output="false">
        <cfargument name="cityName" type="string" />
        <cfset variables.cityName = arguments.cityName />
        <cfreturn this />
    </cffunction>
    <!--- Setter Method --->
    <cffunction name="setName" output="false">
        <cfargument name="newName" type="string" />
        <cfset variables.cityName = arguments.newName />
    </cffunction>
    <!--- Getter Method --->
    <cffunction name="getName" output="false">
        <cfreturn variables.cityName />
    </cffunction>
</cfcomponent>

And the calling page:

<cfset cityObject = CreateObject("component","com.city").init("Chicago") />

<cfoutput>
    #cityObject.getName()# <br />
    #cityObject.setName("New York City")#
    #cityObject.getName()#
</cfoutput>

One thing you will notice here, is that when we created our object with the CreateObject() function, we also attached the init() method to it (with an argument as well). This is common practice with the init method and is a way to make sure it is initialized upon object creation. We also changed our cityName variable and gave it a new name via the setter method between our <cfoutput> tags.

Now let’s modify our city.cfc component and make it even better:

<cfcomponent displayname="city" output="false">
   <cffunction name="init" output="false">
       <cfargument name="cityName" type="string" />
       <cfargument name="country" type="string" />
       <cfargument name="continent" type="string" />

       <cfset setCityName (arguments.cityName) />
       <cfset setCountry (arguments.country) />
       <cfset setContinent (arguments.continent) />
       <cfreturn this />
   </cffunction>

   <cffunction name="setCityName" output="false" returntype="void">
       <cfargument name="cityName" type="string" hint="New cityName value." />
       <cfset variables.cityName = arguments.cityName />
   </cffunction>

   <cffunction name="getCityName" output="false" returntype="string" hint="Returns cityName value.">
       <cfreturn variables.cityName />
   </cffunction>

   <cffunction name="setCountry" output="false" returntype="void">
       <cfargument name="country" type="string" hint="New country value." />
       <cfset variables.country = arguments.country />
   </cffunction>

   <cffunction name="getCountry" output="false" returntype="string" hint="Returns country value.">
       <cfreturn variables.country />
   </cffunction>

   <cffunction name="setContinent" output="false" returntype="void">
       <cfargument name="continent" type="string" hint="New continent value." />
       <cfset variables.continent = arguments.continent />
   </cffunction>

   <cffunction name="getContinent" output="false" returntype="string" hint="Returns continent value.">
       <cfreturn variables.continent />
   </cffunction>
</cfcomponent>

Here we added three arguments that our init() constructor takes, the cityName, country, and continent. One thing that you will notice that is new in this example, is that we <cfset> the setter methods in our component with the arguments that are initialized when our object is created. In our methods we also added the hint attribute, giving a short sentence on what each method (or argument) does. We also put the returntype, which we set to either string (since we are returning a string) or void (not returning anything).

And here is our template that calls for the object creation:


<cfset cityObject = CreateObject("component","com.city").init("St. Louis", "United States", "North America") />

<cfoutput>
    #cityObject.getCityName()#,
    #cityObject.getCountry()#,
    #cityObject.getContinent()#
</cfoutput>

Variable Scopes in Components

The three variable scopes inside components are: this, variables, and var. The this scope allows access to a variable inside the component and also outside of the component. The variables scope privatizes the variable so that it is only accessible inside the component (all the methods can use it). The var scope is only accessible inside a method/function and can not be referenced outside of that method/function. It’s usually good practice to make variables and functions private that our not directly being referenced by the calling template.

Tags: cfcomponent, constructor, getter, init, pseudo-constructor, setter

Advanced CFML 1: Introduction to Objects and Classes

Welcome to the Advanced CFML series. In these tutorials we are going to be going over advanced features that are shared with all the CFML application servers (Adobe ColdFusion, OpenBlueDragon, and Railo). One of the main subjects we will be covering in the advanced series is object-oriented programming and all the various topics that you will encounter with it.

Object-Oriented Programming: Introducing ColdFusion Components

In this tutorial, I am going to introduce you to the world of object-oriented programming with CFML. In CFML, classes are known as components, and components are saved in a “.cfc” extension compared to the “.cfm” extension that we are familiar with. The “.cfc” stands for “ColdFusion Components” in case you were wondering. Before I go any further, I want to explain what classes and objects are.

A class is basically a blueprint for building a house, a dog, a country, etc (metaphorically speaking). Let’s say we have a component (.cfc) called dog.cfc, and inside it we want to build a dog. We are going to put two main ideas inside our component, and those ideas are state and behavior. State is also known as instance variables, and behavior is also known as methods (which you can think of as the same thing as functions). Now, before you get confused, let’s go over this. What kind of (instance) variables does a dog need? How about: the color of the dog, the size of the dog, the breed of the dog, and also the name of the dog. Now what kind of methods (functions) would we like our dog to preform? How about: bark(), fetchNewspaper(), goPotty(), etc.

Now an object, is an instance of a class. When we designed a class, we were thinking about what an object should know (the state), and what an object should do (methods). So referencing our example dog.cfc, when we create an object we want to create it of a particular type, and the class is the blueprint for that type. To make this very straightforward, we can create many different types of dogs (objects), and they all follow the same blueprint (class aka component), and each dog we create (object) can have a different size, color, breed, name, etc. Another abstract example of objects and classes would be making a movie class, and assigning that class the instance variables: title, director, genre, and rating. Then assigning the class a method such as: playMovie(). Now we can create objects of that class, and each object can have differing states and behaviors.

To create our objects, we do this from our templates, and we can create many objects of the same class (component). A real web application example of this would be a shopping cart. Our shopping cart component would have instance variables such as the cart contents, and methods that add/remove from the cart, checkout, etc.

Creating our first CFC

We are going to create our first component and save it as city.cfc (make sure to use the .cfc extension). Let’s also make a folder and title it “com” and place our city.cfc inside it (com will stand for component, just a better way to organize our components). Inside our component we are going to use the <cfcomponent> tag to wrap everything inside the cfc.


<cfcomponent displayname="city" output="false" hint="This is our first CFC.">

</cfcomponent>

All the attributes of the <cfcomponent> tag are optional. The “displayname” is just a name that we give our component, and it should match the name we save our component as. The output attribute suppresses any whitespace inside our component, and if we chose to set this attribute to “true”, that would allow us to put expressions inside of # signs without having to use <cfoutput> tags. The hint attribute is basically just a description of the component. Now let’s add some content into our component.

<cfcomponent displayname="city" output="false" hint="This is our first CFC.">
    <cfset this.myCity = "St. Louis" />
    <cfset this.anotherCity = "Chicago" />
</cfcomponent>

Here we used our <cfset> tag to add two variables to our component. You will notice that we used a scope called this. The this scope allows us to access variables inside our component, and also from regular cfm templates. To go ahead and illustrate this, let’s create a standard cfm template and title it city.cfm. Let’s save this in our examples folder (not in the com folder we created, which is for components only).

<!--- Let's create our first object --->
<cfset cities = CreateObject("component","com.city") />

<cfoutput>Here are two cities: #cities.myCity#, #cities.anotherCity#.</cfoutput>

Here we created an object and named it “cities”. To create this object we used the CreateObject function, which takes two arguments. The first argument we want to use “component”, and the second argument we want to specify what component we want to create an object out of. By saying “com.city” we are telling the function that our component is inside the “com” folder, and we use the “.” with the name of the component (which is “city”). Since our variables “myCity” and “anotherCity” are of the this scope, we can access them directly. Notice that when you call these variables you don’t want to use #cities.this.myCity# format, this will produce an error (we don’t have to fully scope the name of the variable in the template).

Also, if you left out the this scope in declaring your variables inside your component and tried to access those variables, this will create a runtime error that says that the variables do not exist. This would mean that the variables are in the “variables” scope and are not accessible outside of the component. By default all variables are assigned the “variables” scope.

Pseudo-Constructor

Once you have created your <cfcomponent> tags, any code that is place after that tag but before any <cffunction> tag up at the top of your component is called a pseudo-constructor. This means that this code will be executed automatically when an object is created. So far we haven’t created any user-defined functions inside our component (which we will get to in our next tutorial).

Let’s modify our city.cfc and city.cfm examples.

<cfcomponent displayname="city" output="false" hint="This is our first CFC.">
    <cfscript>
    this.myCities = StructNew();
    this.mycities.City1 = "Atlanta";
    this.mycities.City2 = "New York";
    this.mycities.City3 = "Seattle";
    this.mycities.City4 = "Omaha";
    </cfscript>
</cfcomponent>

All the variables inside our structure above will automatically be set to their assigned values each time an object is created.

<cfset cities = CreateObject("component","com.city") />

<table border="1">
<tr>
 <th>City Key</th><th>City Name</th>
</tr>
<cfloop collection="#cities.myCities#" item="i">
 <cfoutput>
 <tr>
 <td>#i#</td><td>#cities.myCities[i]#</td>
 </tr>
 </cfoutput>
</cfloop>
</table>

Here we used a <cfloop> to loop through the structure that is inside our component. We set the collection attribute to “cities.myCities”, cities being the object we created with our CreateObject function, and myCities being the structure inside our city.cfc. Then we looped through everything inside the structure and displayed it inside our HTML table.

If you are unfamiliar with structures, make sure to go over our tutorial on structures.

Tags: cfcomponent, classes, object-oriented programming, objects, pseudo-constructor, this

CFML Tutorial 20: Recursion

Time to break away from forms and their interaction with a database, and time to get back into user-defined functions. I want to show you something that you might encounter, and that is the use of recursion with UDF’s.

Using Recursion with User-Defined Functions

Recursion is when we have a function (user-defined function) and inside that function we call the function itself. Sounds confusing doesn’t it? To better understand this, let’s talk about factorials and what they are. Let’s say n is 5, we would write this as 5! which would be the same thing as saying (5 x 4 x 3 x 2 x 1), this would come out to being 120. It is basically whatever the number, n, times all the way to one. This is essentially what a factorial is.

Let’s create a template and name it factorial.cfm, and paste this source code into it:

<cffunction name="Factorial" returntype="numeric" output="yes">
	<cfargument name="n" type="numeric" />
	<cfif arguments.n eq 1>
		<cfreturn 1 />
	<cfelse>
		<i>n</i> is now #arguments.n# <br />
		<cfreturn arguments.n * Factorial(arguments.n-1) />
	</cfif>
</cffunction>

<cfoutput> #Factorial(5)# is 5! </cfoutput>

Let’s go over this example so that you will have a thorough understanding of it. In our last line of code between the <cfoutput> tags we called a UDF that we created, called “Factorial”, and passed an argument of 5 into it. Up in our <cffunction> you can see we added two attributes to it, one specifying the return type, and the other allowing us output (this means basically our function is wrapped around in <cfoutput> tags so that we can call variables via the pound signs). So 5 is passed into our <cfargument> tag, which checks to see if it is numeric since we added that attribute. We have an if-statement that checks to see if the argument n is equal to one, n is 5 so it goes straight to the else-statement. The else-statement prints “n is now 5″, then we hit the <cfreturn> tag that returns 5 times  the Factorial(5-1), which translate into 5 times Factorial(4). Factorial(4), has the argument of 4 which is then passed to the function Factorial(), then we get to 4 times Factorial(4-1)….3 times Factorial(3-1)… 2 times Factorial(2-1)… then our if-statement becomes true.

The if-statement (which checks to see if n is equal to 1) is what is called a base case, it is what stops the recursion process from becoming an infinite loop. Now that n is equal to 1, the <cfreturn> tag returns 1. Halting the function from processing the <cfelse> statement again. Now the Factorial function can answer all the questions that it was trying to return… 5 times Factorial(4) all the way to 2 times Factorial(1), which results into 120.

You might ask yourself what the heck, how did all of this stuff get stored, and then once it hit the initial return statement, the one that returns 1, print the sum of 120? This is where recursion gets tricky, and is a hated topic of computer science. Most tutorials will stop here and not go any further. And you would just go on blind faith that this technique somehow works. In the second <cfreturn>, every iteration of that return statement stores that value into a section of memory called “the stack”.

To briefly go over the stack, let’s think of terms of functions. When you call a function, the computer has to remember the spot where you called that function, then go to that particular function. When it goes to that function there may be other functions inside that function. So it has to remember another spot. It tosses each remembrance on top of each other, which you can now visualize as a stack of papers. Then it goes back and returns the results starting with the top of the stack.

Going back to our example, I am going to go over this entire process with just a simple 3! factorial for a better understanding.

[3 * Factorial(3-1)] – N is now 3, the value of N is now known, but the value of Factorial(3-1) is not known. So the value of 3 is stored into the stack (which is a section of memory).

[2 * Factorial(2-1)] – N is now 2, the value of N is now known, but the value of Factorial(2-1) is not known. So the value of 2 is stored into the stack.

The Factorial function now calls itself with the value of 1, Factorial(1), so now the if-statement kicks in and returns one. Now the value of Factorial(1) is now known, once this occurs it becomes a backwards loop and reverts back to it’s second execution. Pulls up the value 2 from the stack and times it by Factorial(1), which now equals Factorial(2), and pulls up again from the stack, the value of 3 and times that by Factorial(2), which is now 6, and this is the value the function finally returns (since there is nothing left in the stack).

As a note, the stack is limited, and there is only so much that it can hold. So if you do something like this:

<cffunction name="CrashMe" returntype="numeric" output="yes">
	#CrashMe()#
</cffunction>

<cfoutput> #CrashMe()#</cfoutput>

This would make the application server toss an error after spending time processing it. This would keep calling itself non-stop, over and over again, and since the stack is limited, it will crash.

How would you write our Factorial function in a standard index loop (for loop)?

<cffunction name="IndexFactorial" returntype="numeric" output="yes">
    <cfargument name="n" type="numeric" />
    <cfset variables.value = 1 />
    <cfloop index="i" from="1" to="#n#">
        <i>n</i> equals #arguments.n# <br />
        <cfset variables.value = variables.value * #arguments.n# />
        <cfset #arguments.n# = #arguments.n#-1 />
    </cfloop>
    The factorial(<i>n</i>) is equal to:
    <cfreturn variables.value />
</cffunction>

<cfoutput> #IndexFactorial(5)#</cfoutput>

You could have also written this example as a conditional (while) loop. As you can see, the recursive factorial function was more elegant compared to the index loop factorial example. Sometimes it is better to use a recursive function to do work, it just depends.

Let’s go over this example. We called our function, IndexFactorial, with the argument of 5, which is passed to n inside our function. We set a variable named value to 1, then we begin our index loop. The index attribute is set to “i”, our from attribute is set to 1, and our “to” attribute is set to n, which is 5. The loop displays each iteration of n, it also sets the variable “value” to value times n. So variables.value equals 5 (1 times 5). The next line sets the value of n as n-1, which means that n now equals 4. Now we go back to the top of the loop for our second iteration, variables.value is set to “5 times 4″, and n is now set to 3, and these iterations continue on. Once n is equal to zero, the index loop exits out and returns the value of variables.value.

Fibonacci Sequence

One of the classic uses of displaying recursion is via the Fibonacci Sequence.

<cffunction name="Fib" returntype="numeric" output="yes">
    <cfargument name="n" type="numeric" />
    <cfif (arguments.n eq 0) or (arguments.n eq 1)>
        <cfreturn arguments.n />
    <cfelse>
        <cfreturn Fib(arguments.n-1) + Fib(arguments.n-2) />
    </cfif>
</cffunction>

<cfoutput> #Fib(10)#</cfoutput>

How the Fibonacci Sequence works is that a number, in the sequence, is made up of the sum of the two previous numbers. Here are the first ten numbers of the sequence: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]. So the 10th number in this sequence is 55, that number is the sum of 21 + 34.

Recursion can become very complicated, and this tutorial is just an introduction to the topic.

Tags: factorial, fibonacci, recursion, user-defined functions