Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Divergent CALLER Scope Assignment Behavior In Adobe ColdFusion And Lucee CFML 5.3.7.48

By Ben Nadel on
Tags: ColdFusion

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:

Variables and Url scope after caller assignment in Adobe ColdFusion 2018 shows URL scope has been updated.

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:

Variables and Url scope after caller assignment in Lucee CFML 5.3.7.48 shows VARIALBES scope has been updated.

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 to caller.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.



Reader Comments

@All,

Small update - possible work-around for consistency. If you use the <cfparam> tag to assign values into the caller scope, it works consistently across ACF and Lucee. Meaning, if you have this in a ColdFusion custom tag:

<cfset target = "url.foo" />
<cfset caller[ target ] = "bar" />

... this does not work the same in ACF and Lucee. But, if you have this:

<cfset target = "url.foo" />
<cfparam name="caller.#target#" value="bar" />

... 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.

Reply to this Comment

Over on Twitter, Dan G. Switzer, II mentioned that this would be a good use-case for the setVariable() function in ColdFusion. As in:

<cfset target = "url.foo" />
<cfset setVariable( "caller.#target#", "bar" ) />

I haven't tested this, but it sounds right.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Blog
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.