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 »
304 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 »
304 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 »
10,640 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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »
Feb 9, 2012 at 10:29 PM
Learning ColdFusion 9: Application-Specific Data Sources
@Ben, No offence, but if people were really wanting advanced features they would be using a platform like ASP.NET MVC. CFML is so structurally compromised as a tag-based scripting language that ... read »
Feb 9, 2012 at 10:03 PM
Subversion - Cleanup Failed To Process The Following Paths
@Leviaguirre, do you still have problems with this? ... read »