ColdFusion Custom Tag CALLER Scope Uses Special Structure Notation
Posted August 28, 2006 at 4:01 PM
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:
Launch code in new window » Download code as text file »
- <!--- 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:
Launch code in new window » Download code as text file »
- <!--- 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:
| | | | ||
| | ![]() | | ||
| | | |
However, let's take a look at the line that actually sets the value:
Launch code in new window » Download code as text file »
- <!--- 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:
Launch code in new window » Download code as text file »
- <!--- 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:
Launch code in new window » Download code as text file »
- <!--- 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:
| | | | ||
| | ![]() | | ||
| | | |
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.
Download Code Snippet ZIP File
Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Newer Post
Color Coding My Code Samples - UGGG!
Older Post
Thanks To David Ries For Google AdWords Help
Reader Comments
I'd definitely consider this a bug. caller[...] should set a key in the variables scope. Did you enter a report for this?
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.
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.
I will report it.
This has soooo been reported ;)
I am just testing the new "remember my information" part of the comments posting.
Sweeet. It totally remembered me :)






