School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,015 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,076 people online right now. Registration is fast and FREE... Join Now!




<cfreturn> tag and other issues

 

<cfreturn> tag and other issues, return statement at the end of the function - A MUST?

ComboAlex

6 Aug, 2009 - 07:34 AM
Post #1

New D.I.C Head
*

Joined: 31 Jul, 2009
Posts: 25


My Contributions
Hey there my expert friends. smile.gif I would really need your help here about the <cfreturn> tag. I saw there was already a topic on a similiar subject, but I decided to make a new topic, because I included some other stuff too.

I will be very grateful if someone can give me some advice, because I have a great need to learn ColdFusion.

I am not new to programming, but I am relatively new to ColdFusoin. I already have experience in PHP, Java, C, ... so I am aware of the basic concepts of programming such as functions / methods, return values, classes / objects, recursive functions and so on. So, Now I am trying to develop a simple recursive, database driven navigation, but came across some basic problems, which I couldn't find the solution on the internet.

I've came across many great tutorials which were very good practice for me and I learned many interesting new things, but somehow nothing suited my needs.

Writing functions in C (or methods in Java) with return statements it's nothing new to me. Writing functions that "return something" became a great asset to me and eventually I couldn't see myself programming in some other way other than using the "modular way" with functions that return something. Once you get used to it, there is no way back, cause functions are such a great asset.

Now, here it gets interesting. Recently I encountered a problem while using <cfreturn> tags in ColdFusion documents. You see, it is for me a normal thing that once you write a return statement in a Java methods or C functions, you immediately exit the function / method where you've entered the return statement. The compiler literally skips the lines in the function/method after the return statement. My question is: WHY IS THIS NOT HAPPENING IN COLDFUSION? Did I miss something here?

Let me show you the code of the CF function I am using to build a bread crumb type of navigation. I will also use this function to make a database-driven navigation menu as shown on this website: click which I made with PHP... also recursively.

So, here is my code and the <cfreturn> tag that is bothering me. I explained everything in the comments in the code and also at the end of the code there is a print screen of the database definition that I use for this example (many thanks to Doug Boude and others that keep on writing great articles and tutorials).

I tried to keep it as simple as possible, so don't get stuck on the simplicity of the database table, cause there are some columns missing, but are not important for my example. biggrin.gif

CODE

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Navigation</title>
</head>

<body>

<!--- array reversing --->
<cffunction name="reverseArray" access="public" returntype="array">
    <CFARGUMENT name="inputArray" type="array" required="yes" default=0 >
    
    <CFSCRIPT>            
        For (i = 1; i LTE (ArrayLen(inputArray)/2); i++)
        {    
            temp1 = i;
            temp2 = ArrayLen(inputArray) + 1 - i;                     
            newArray[i] = inputArray[temp2];
            newArray[temp2] = inputArray[temp1];                                            
        }
        if (ArrayLen(inputArray) mod 2 != 0)
            newArray[(ArrayLen(inputArray)+1)/2] = inputArray[(ArrayLen(inputArray)+1)/2];
        
        return newArray;
        <!---
        DOES THIS RETURN STATEMENT WORKS EXACTLY AS A <CFRETURN> STATEMENT?
        DOES THE FUNCTION EXIT WHENEVER AND ALLWAYS WHEN WE CALL A RETURN STATEMENT IN COLDFUSION?
        I KNOW FROM OTHER LANGUAGES THAT IT DOES. I AM NOT SURE ABOUT COLDFUSION, EVEN THOUGH I KNOW COLDFUSION RUNS ON JVM (JAVA VIRTUAL MACHINE).
        I EVEN SAW THAT WHEN COLDFUSION COMPILES IT'S CODE, IT COMPILES DATA IN THE EXACT WAY AS THE COMPILER IN JAVA... AM I RIGHT?
        --->
    </CFSCRIPT>    
    
</cffunction>

<!--- THE FUNCTION IS RECURSIVE AND IT RECIEVES TWO NUMERIC ARGUMENTS WHICH ARE CHANGED WITH EVERY RECURSIVE CALL (line 55)--->
<!--- THE FUNCTION IS SUPPOSED TO RETURN AN ARRAY FOR LATER USE IN OTHER FUNCTIONS --->
<cffunction name="MakeBreadCrumb" access="public" returntype="array">
    <!--- setting the required function arguments --->
    <CFARGUMENT name="id" type="numeric" required="yes" default=0 >
    <CFARGUMENT name="cnt" type="numeric" required="yes" default=0 >            
    
    <!--- we make a new array which will hold all the parents, but we declare it only the first time in the recursive call --->
    <!---
    IS THIS THE RIGHT WAY TO DO IT? OR IT IS BETTER TO SET A NEW ARRAY OUTSIDE OF THIS FUNCTION? FROM MY EXPERIENCE IT'S
    BETTER TO HAVE ALL THE STRUCTURES (SUCH AS ARRAYS) THAT ARE DIRECTLY RELATED TO A SPECIFIC FUNCTION INSIDE THE SAME
    FUNCTION AND THEN MAKE SO THAT THE FUNCTION ITSELF RETURNS THE ARRAY, SO WE CAN LATER ON USE IT. AM I RIGHT?
    --->
    <cfif arguments.cnt IS 0>        
        <cfset breadCrumbArray=ArrayNew(1)>
    </cfif>    
    
    <!--- selecting the current parentid --->    
    <cfquery name="qryItem" datasource="test">
        SELECT parentid
        FROM testnavigation
        WHERE id = #arguments.id#
    </cfquery>
    
    <!--- saving the current parentid to an array --->
    <cfset breadCrumbArray[#arguments.cnt#]=arguments.id>
    
    <cfif qryItem.parentid IS NOT 0>
        <!--- HERE WE MAKE THE RECURSIVE CALL of MakeBreadCrumb - the input argument becomes the current <parentid> from the <qryItem> query --->
        <cfset MakeBreadCrumb(id = qryItem.parentid, cnt = cnt + 1) >
    <cfelse>
        <!--- we reverse the breadCrumb array co we can "follow the bread crumbs" from start to the end in the correct order --->    
        <cfset reversedBreadCrumbArray = reverseArray(inputArray = breadCrumbArray)>
        <cfdump var="#reversedBreadCrumbArray#" label="The correct order of the 'bread crumbs'">
      
        <cfreturn #reversedBreadCrumbArray#>
        <!------------------------------------>
        <!--- MOST IMPORTANT QUESTION HERE --->
        <!------------------------------------>
        <!---
        HERE WE SHOULD EXIT THE FUNCTION BECAUSE WE USED THE RETURN STATEMENT. WHY THEN THE CF ERROR REPORT SAYS:        
        "The value returned from the MakeBreadCrumb function is not of type array."        
        the error occurred in E:\ColdFusion\wwwroot\cfdocs\Recursive Navigation\alexnavigation.cfm: line 54
        Called from E:\ColdFusion\wwwroot\cfdocs\Recursive Navigation\alexnavigation.cfm: line 54            
        54 :         <cfset MakeBreadCrumb(id = qryItem.parentid, cnt = cnt + 1) >                
         --->
        
    </cfif>
    
        <!---        
         WHY IS IT THAT WHEN I PUT THE <CFRETURN> STATEMENT HERE (THAT IS OUTSIDE OF THE <CFIF> STATEMEN, AT THE EXACT END OF THIS FUNCTION)
         THE FUNCTION SEEMS TO WORK PROPERLY AND IT DOESN'T RETURN ANY ERROR?         
         --->                  
    
</cffunction>

<!--- Let's call the function that makes the breadCrumb --->
<cfset bcArray = MakeBreadCrumb(id=URL.item, cnt=1)>

<!---
PLEASE, SOMEONE TELL ME IF IT'S BETTER TO HAVE PRIVATE FUNCTIONS IN CF COMPONENTS. WILL I BE ABLE TO USE / CALL THEM OUTSIDE OF THIS FILE?
I KNOW THAT IN JAVA CLASSES THIS IS NOT POSSIBLE IF FUNCTIONS ARE PRIVATE
--->

</body>
</html>

Here is the database definition. Again, it is only for testing purposes, so for now the content is just random.
IPB Image

This post has been edited by ComboAlex: 6 Aug, 2009 - 11:28 AM

User is offlineProfile CardPM
+Quote Post


xheartonfire43x

RE: <cfreturn> Tag And Other Issues

7 Aug, 2009 - 11:36 AM
Post #2

D.I.C Regular
***

Joined: 22 Dec, 2008
Posts: 267



Thanked: 2 times
My Contributions
What you might want to do is to put a simple <cfexit> tag after the <cfreturn> tag. I am not 100% sure if this will work for you, but you might. You may want to check the livedocs on it though.

User is offlineProfile CardPM
+Quote Post

ComboAlex

RE: <cfreturn> Tag And Other Issues

7 Aug, 2009 - 12:32 PM
Post #3

New D.I.C Head
*

Joined: 31 Jul, 2009
Posts: 25


My Contributions
Thank you very much for your help. I already realized that it's a big chance that the compiler somehow never gets to the <cfreturn> statement. Or there must be some other logical reason that this stuff didn't work. Why I am I so sure about that? Well, I didn't stop to much at this problem and went on towards the end of my recursive Navigation application that I am so passionately trying to solve... so I went on with coding and was forced to try the <cfreturn> statement in other cases, other functions. One very simple is this functions where I am checking if a given value exists in a given array.

Here's the code:
CODE

<!--- the function returns a boolean value (true or false) depending if the input argument is in
the specified array - WORKS OK --->
<cffunction name="inArray" access="public" returntype="boolean">
    <cfargument name="element" type="numeric">
    <cfargument name="inputArray" type="array">
    
    <cfset arrayLength = ArrayLen(arguments.inputArray)>            
    
    <cfloop from="1" to="#arrayLength#" index="i">        
        <cfif arguments.inputArray[i] EQ arguments.element>                        
            <cfreturn true>
            <!--- if this happens only once it's enough to say that the element exists in the inputArray,
            so we exit the function here  --->          
        </cfif>         
    </cfloop>    
    
    <!--- if we get until here it means that the <cfif> statement above was never true and it's content was every time
    skipped--->
    <cfreturn false>
</cffunction>


Now my problem is not anyomore the poor <cfreturn> statement, but the whole recursive database driven navigation I am trying to develop. I will soon post a new topic, because I am so terribly stuck almost at the end line!!! I almost did it,... I hope a good sleep will help as it did many times. biggrin.gif

As I said, I am a beginner in CF (not in overall programming) and I must say that the example is great practice... not only for me, but for everyone that wants to learn CF. Soon will post my whole code with my questions.

Cheers! icon_up.gif
User is offlineProfile CardPM
+Quote Post

ComboAlex

RE: <cfreturn> Tag And Other Issues

7 Aug, 2009 - 01:28 PM
Post #4

New D.I.C Head
*

Joined: 31 Jul, 2009
Posts: 25


My Contributions
As promised here is my post with a new problem. Thanks in advance to everyone that will try to help.

Alex
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/21/09 07:31AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month