Skip to main content
Participating Frequently
December 30, 2010
Question

CF9 - cfinvoke seems to search scopes in different order

  • December 30, 2010
  • 3 replies
  • 1227 views

We came across this in a legacy app when it was moved to CF9 -- a cfinvoke that had always worked in previous versions seemed to stop working whereas invoking the same method using function notation returned the right results.

I've only tested the following on CF9 but it demonstrates the problem we had on CF9 which did not exist in previous versions.

This uses cfinvoke and function notation to call the same method and they return two different results -- cfinvoke returns an emptry struct, the function notation returns a correctly populated struct.

Application.cfm:

<cfapplication name="cf9test"
    sessionmanagement="Yes"
    setclientcookies="Yes"
    sessiontimeout="#createTimeSpan(0,0,60,0)#"
    applicationtimeout="#createTimeSpan(1,0,0,0)#">

test.cfc:

<cfcomponent output="true">
   
    <cffunction name="func1" returntype="struct">
        <cfargument name="stObject" required="no" default="#structNew()#">
        <cfinvoke component="#this#"
            method="func3"
            returnVariable="stObject"><!--- Returns into Variables scope --->
        <!--- Returns the empty struct in arguments.stObject --->   
        <cfreturn stObject/>
    </cffunction>

    <cffunction name="func2" returntype="struct">
        <cfargument name="stObject" required="no" default="#structNew()#">
        <cfscript>
            stObject = func3(); // Returns into Arguments scope
        </cfscript>
        <cfreturn stObject/>
    </cffunction>

    <cffunction name="func3" returntype="struct">
        <cfscript>
            stTest = structnew();
            stTest.foo = "blah";
            stTest.blah = "bingo";
        </cfscript>
   
        <cfreturn stTest />
    </cffunction>

</cfcomponent>

index.cfm:

<cfinvoke component="cf9test.test"
        method="func1"
        returnVariable="stObject">

Return from the cfinvoke:        
<cfdump var="#stObject#">

<cfset structClear(stObject)>
<br />
<cfinvoke component="cf9test.test"
        method="func2"
        returnVariable="stObject">

Return from the function       
<cfdump var="#stObject#">

    This topic has been closed for replies.

    3 replies

    Participating Frequently
    January 1, 2011

    Good news -- I just installed the 64-bi 9.01 update on my laptop and it seems to have fixed the problem. Now both versions return the value into the arguments scope.

    Thank you for the suggestions. I wasn't too worried about handlng the code that showed up the issue -- the code should be corrected anyway -- just wanted to point out an inconsistency in the way CF was responding as it was confusing when we initially encountered it.

    BKBK
    Community Expert
    December 31, 2010

    I don't see the problem. All you had to do to avoid ambiguity was to var the variables in the methods and to give them distinct names. For example

    <cfcomponent output="false">
        <cffunction name="func1" returntype="struct" output="false">
            <cfargument name="stObject" required="no" default="#structNew()#">
            <cfset var object1 = structNew()>
            <cfinvoke component="#this#"
                method="func3"
                returnVariable="stObject1">
            <cfreturn stObject1/>
        </cffunction>
        <cffunction name="func2" returntype="struct" output="false">
            <cfargument name="stObject" required="no" default="#structNew()#">
            <cfscript>
                var object2 = structNew();
                stObject2 = func3();
            </cfscript>
            <cfreturn stObject2/>
        </cffunction>
        <cffunction name="func3" returntype="struct">
            <cfscript>
                var stTest = structnew();
                stTest.foo = "blah";
                stTest.blah = "bingo";
            </cfscript>  
            <cfreturn stTest />
        </cffunction>
    </cfcomponent>

    Brainiac
    December 30, 2010

    It's well documented in many "best practice" documents and forum postings to ALWAYS scope your variables for just this reason. You won't get an argument from me that it seems like shoddy programming on Adobe's part as the CF version should not affect the behavior of something like your example, but scoping has been documented since I've been using CF (v. 4.0). Sorry if you were expecting a different answer.

    Participating Frequently
    December 30, 2010

    Steve,

    I don't have a problem with that at all and totally agree on scoping variables. The code where this showed up is quite old (was probably written for CF 6, maybe 7) and there are various things about it that would be done differently. In fact, it was written at a time when something was specifically broken about the interaction between arguments and variables scope in CFCs are there are some oddities in it.

    Anyway, I totally agree on scoping and not depending on CF to do it right.

    But, since we saw the error and traced it down I thought it would be worth posting since it is apparently:

    1) a difference from earlier versions of CF and CF9 and

    2) there are two pieces of code that should produce the same result that don't.

    Again, thanks for the comment!

    d

    Brainiac
    December 30, 2010

    I totally agree and I have to admit, I have quite a bit of old code floating around that does not specify the VARIABLES scope. A thorn in my side is when I go correct some of this older code and specify the scope I have found that "myAssumedVariableScopedVar" and "variables.myAssumedVariableScopedVar" do not always reference the same variable.