So, this was a big thread today on cfcdev that I thought I would share:
If you define a variable as a local scoped variable in a method, and then use the cfinclude tag, any variable that was VAR scoped will be copied over to the Variables scope for the CFC.
So, an example:
alpha.cfc
<cffunction name="foo">
<Cfset var hello = "I am hello">
<cfdump var="#variables#">
<cfinclude template="include.cfm">
<cfreturn "foo was called">
</cffunction>
<cffunction name="get">
<cfdump var="#variables#">
</cffunction>
</cfcomponent>
test.cfm
foo = createObject("component","alpha");
foo.foo();
foo.get();
</cfscript>
Note that it doesn't matter what is in include.cfm.
When you run the code, you will notice that the hello variable gets copied over to the global Variable scope in the CFC. (Thanks to Nathan Dintenfass for the nice and simple example.)
As you can guess, this can lead to some very subtle, hard to detect bugs.
Archived Comments
I don't think this is "bug" -- it seems MACR made a conscious decision to implement this in this way. Nasty.
I agree with the fact this is a bug. I remember during the early beta or NEO, variables set inside a <cffunction> could not be accessed in a <cfinclude>. I guess back they “patched” it by copying the local function scope inside the global request scope. Unfortunately though, I think, this is a design issue that MACR can’t fix unless the start re-architecting ColdFusion. The problem, I think, is the fact that we are allowed to use <cfinclude> inside a <cffunction>. Although this is very convenient, it doesn’t make any sense. <cfinclude>’s are great to re-use code such as headers, footers and menus. Functions though, in my mind, are meant to perform operations and return a value. ColdFusion is, as far as I know, the only web scripting language that allows you to integrate both visual and programmatic operations in functions.
We've run into this a lot within our application, cfquery names being seen from the base cfm files (overwriting queries within the cfm files themselves). This is a fundemental design problem with ColdFusion, and stems from trying to be as "RAD" as possible. The problem is it’s too late for them to change it, as it would break a lot of applications out there.
As ColdFusion continues to add more advanced functionality like CFC’s, more problems will arise. The language needs more structure, but it’s built to not have as much structure as other languages. Take for example variable declaration within a method of a CFC, in almost any other language any variable declared within the method/function stays local (not the case in coldfusion unless you prepend it with var). This causes all sorts of problems if CFQUERY names aren’t scoped to the variables scope etc. The CFINCLUDE problem is the same thing. Most other languages you can’t just include a code template and have its contents visible within the function the way you can with ColdFusion. You have to put the contents of the cfinclude in a function or object etc.
This problem is entirely centered around RAD, and how eventually it interferes with strucuture. It will be interesting to see how Macromedia overcomes this problem, as I think it is only going to become larger over time. Unless Macromedia just wants developers creating relatively simple small to medium sized applications, which is probably at least 75% of the ColdFusion development out there.
Is this still a problem on MX 6.1 with latest updaters?
Thanks!
I'm pretty sure this was fixed in the latest 6.1 release. Pretty sure. Easy enough to test though. :)
I tested and it doesn't appear to be fixed.
This definitely works as expected (that is, the bug isn't present) in MX 7.