ColdFusion Custom Tag CALLER Scope Uses Special Structure Notation

Posted August 28, 2006 at 4:01 PM by Ben Nadel

Tags: ColdFusion

From what I can see, CALLER scope structure notation is a special form of structure notation. Let's take a look at an example. Let's assume that we have a custom tag called my_tag.cfm:

  • <!--- Param attributes values. --->
  • <cfparam name="ATTRIBUTES.name" />
  • <cfparam name="ATTRIBUTES.value" />
  •  
  • <!--- Set value in caller scope. --->
  • <cfset CALLER[ ATTRIBUTES.name ] = ATTRIBUTES.value />
  •  
  • <!--- Make sure tag does not execute twice. --->
  • <cfexit method="EXITTAG" />

All this tag does is take a variable name and value and sets the value into the variable name in the caller scope. Let's call this as a custom tag and send in a variable name:

  • <!--- Create an empty structure. --->
  • <cfset REQUEST.Data = StructNew() />
  •  
  • <!--- Create two keys for testing. --->
  • <cfset REQUEST.Data[ "anne" ] = "" />
  • <cfset REQUEST.Data[ "sarah" ] = "" />
  •  
  • <!--- Set value. --->
  • <cf_my_tag
  • name="REQUEST.Data.anne"
  • value="hot"
  • />
  •  
  • <!--- Set value. --->
  • <cf_my_tag
  • name="REQUEST.Data.sarah"
  • value="crazy hot!"
  • />

This tag executes as you would expect it to. The two values are stored into their appropriate variables as in the CFDump below:


 
 
 

 
CFDump - CALLER Scope  
 
 
 

However, let's take a look at the line that actually sets the value:

  • <!--- Set value in caller scope. --->
  • <cfset CALLER[ ATTRIBUTES.name ] = ATTRIBUTES.value />

If you think about what the ATTRIBUTES.name is, it's a string value that stands for a variable name. In one case above, I am passing in the value "REQUEST.Data.sarah". That means that the custom tag line can evaluate to:

  • <!--- Set value in caller scope. --->
  • <cfset CALLER[ "REQUEST.Data.sarah" ] = ATTRIBUTES.value />

And, in fact, if you replace that line of code, it does run correctly, but only storing values into REQUEST.Data.sarah. But look at what is going on here: CALLER is a struct that is using a variable name as a key. Let's look at a quasi-parallel example that does not include a custom tag:

  • <!--- Create another empty structure. --->
  • <cfset REQUEST.Girls = StructNew() />
  •  
  • <!--- Create two keys for testing. --->
  • <cfset REQUEST.Girls[ "ashley" ] = "" />
  • <cfset REQUEST.Girls[ "julie" ] = "" />
  •  
  • <!---
  • Set value. Try to mirror this:
  • <cfset CALLER[ ATTRIBUTES.name ] = ATTRIBUTES.value />
  • --->
  • <cfset REQUEST[ "Girls.ashley" ] = "hot" />
  • <cfset REQUEST[ "Girls.julie" ] = "super hot!" />

In this example, we are trying to treat the REQUEST scope in the same way that we treat the CALLER scope. We are passing it a variable name in the hopes that it will evaluate properly as it did in the custom tag. However, as you can in the following CFDump, it does not:


 
 
 

 
CFDump - REQUEST Scope to Mirror CALLER Scope  
 
 
 

Instead, what it did is use the variable name as a whole to create a key in the REQUEST scope. Honestly, this is how I though the CALLER scope would have worked as well, but it must be some sort of special notation that I am unaware of. Anyway, it's worth noting that you can use CALLER slightly differently than any other scope that I can see, unless I am missing something critical.




Reader Comments

Aug 29, 2006 at 11:39 AM // reply »
319 Comments

I'd definitely consider this a bug. caller[...] should set a key in the variables scope. Did you enter a report for this?


Aug 29, 2006 at 11:44 AM // reply »
319 Comments

Interesting. Ignore the request scope, and just do

caller["a.b"] = 1 and it makes an A structure. That is definitely a bug I'd say.


Aug 29, 2006 at 11:45 AM // reply »
74 Comments

Ray,

I am not sure if this is a bug... if it was, how would you be able to store return data into a nested variable?

I suppose, if it is a bug, you could do something like:

<cfset "CALLER.#ARGUMENTS.return#" = XYZ />

That should work as expected and would allow you to store into nested objects within the caller scope.


Aug 29, 2006 at 11:49 AM // reply »
74 Comments

I will report it.


Aug 29, 2006 at 11:54 AM // reply »
74 Comments

This has soooo been reported ;)


Aug 29, 2006 at 2:36 PM // reply »
74 Comments

I am just testing the new "remember my information" part of the comments posting.


Aug 29, 2006 at 2:37 PM // reply »
74 Comments

Sweeet. It totally remembered me :)


Feb 22, 2011 at 6:01 PM // reply »
6 Comments

Hi

can a custom tag call a javascript function in the caller or access any div tag from the caller.

Thanks
Chaz


Feb 22, 2011 at 6:07 PM // reply »
11,238 Comments

@Chaz,

There is no Javascript being run on the server (most likely). As such, you can't execute Javascript from within a custom tag.


Post A Comment

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.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
May 20, 2013 at 4:29 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, That's if you're trying to reference a specific row. In this case, we're trying to reference the entire query column as one cohesive value. So, you are correct that if you wanted to output a ... read »
May 20, 2013 at 4:24 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I thought when you used array notation to reference queries you always had to have the row or it would throw a similar error as well? ... read »
May 20, 2013 at 11:45 AM
Using jQuery's Animate() Step Callback Function To Create Custom Animations
This is really useful. I found out that you don't actually have to use a dummy css property (surprisingly). To animate a property in a linear-gradient for instance I did this this.css('someLinearGra ... read »
May 20, 2013 at 10:51 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Josh, Oh snap! You're totally right! I'm not sure I've ever tried that. I did know that you can call a number of other array-methods on ColdFusion query columns: http://www.bennadel.com/blog/167 ... read »
May 20, 2013 at 10:45 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Ben - I believe you can achieve the same functionality with ColdFusion's built in ArrayToList() function. ArrayToList( users[ "id" ] ); ... read »
May 20, 2013 at 10:21 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Is there any error logging and handling framework in angularjs, if not then in what way I can do this. ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools