Divergent CALLER Scope Assignment Behavior In Adobe ColdFusion And Lucee CFML 5.3.7.48
In my recent foray into ColdFusion custom tags, I've stumbled upon a divergent behavior between Adobe ColdFusion and Lucee CFML in terms of CALLER
scope assignment within a custom tag. Dating all the way back to 2008, I've demonstrated that the CALLER
scope is somewhat magical in how it treats variables references; which, allows for a simpler mental model. It seems, however, that in Lucee CFML some of that magical behavior is, well, not as magical.
What I'm referring to is the CALLER
scope's ability to be treated more like a "tunnel" into the calling context as opposed to simple "scope". In Adobe ColdFusion, this "tunnel" treats "keys" almost like a deferred value that is evaluated in the calling context. For example, imagine that we have a ColdFusion custom tag that attempts to set a value into the URL
scope via the CALLER
scope:
<cfset caller[ "url.setViaCaller" ] = "Test 1,2,3" />
<cfexit method="exitTag" />
With a "traditional struct", attempting to use the key, url.setViaCaller
, would simply treat the string as an opaque token and assign the key, url.setViaCaller
, into whatever the parent struct is. With the CALLER
scope, however, keys get a special treatment: instead of being treated as an opaque token, the key url.setViaCaller
is evaluated in the calling context.
As such, if we run the following ColdFusion code in Adobe ColdFusion 2018:
<cf_caller_test />
<!--- Output the platform runtime. --->
<cfif server.keyExists( "lucee" )>
<cfdump var="LUCEE: #server.lucee.version#" />
<cfelse>
<cfdump var="ACF: #server.coldfusion.productVersion#" />
</cfif>
<!--- See which scope received the CALLER assignment. --->
<cfdump var="#url#" label="URL" />
<cfdump var="#variables#" label="VARIABLES" />
... we get the following output:
As you can see, assigning url.setViaCaller
into the CALLER
scope evaluates the string in the calling context. As such, it ends up assigning the key setViaCaller
into the URL
scope.
Now, if we run this same code in Lucee CFML 5.3.7.48, we get a different output:
As you can see, assigning url.setViaCaller
into the CALLER
scope treats the string as an opaque token and ends up assigning the key into the VARIABLES
scope, not the URL
scope.
ASIDE: The
CALLER
scope can still act as a "tunnel", it just needs to be more explicit. For example, assigning a value tocaller.url.setViaCaller
- using dots-notation only - works the same in Adobe ColdFusion and Lucee CFML.
ColdFusion custom tags don't get used all that often; so, there's a good chance no one else has run into this issue before (Google certainly didn't turn up any matching hits). That said, just something to be aware of as a difference between the two CFML engines.
Want to use code from this post? Check out the license.
Reader Comments
@All,
I filed an incompatibility ticket with Lucee: https://luceeserver.atlassian.net/browse/LDEV-3309
@All,
Small update - possible work-around for consistency. If you use the
<cfparam>
tag to assign values into thecaller
scope, it works consistently across ACF and Lucee. Meaning, if you have this in a ColdFusion custom tag:... this does not work the same in ACF and Lucee. But, if you have this:
... where you use the
<cfparam>
in lieu of direct assignment, this does work consistently in both ACF and Lucee. So, a possible work-around if you need to get something to function properly.Over on Twitter, Dan G. Switzer, II mentioned that this would be a good use-case for the
setVariable()
function in ColdFusion. As in:I haven't tested this, but it sounds right.
@All,
This morning, I already made use of the
caller.#key#
concept in a code kata in which I create acf_specify
ColdFusion custom tag that wraps the nativecfparam
tag and exposes more error information:www.bennadel.com/blog/3996-custom-cfparam-tag-that-exposes-error-information-in-lucee-cfml-5-3-7-48.htm
@All,
I ran into this again - if you have a variable "key" that contains invalid variable-name characters, Adobe ColdFusion will throw an error unless you explicitly reference the
variables
scope:www.bennadel.com/blog/4065-strange-variable-name-error-when-writing-to-base-tag-in-adobe-coldfusion-2018.htm
I assume this is a related issue and relates specifically to the fact that the
caller
scope is "magical" in Adobe ColdFusion but "just a struct" in Lucee CFML.