Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with: Alexander Friess

Testing CALLER.Scope.Value And Caller[ "Scope.Value" ] In ColdFusion Custom Tags

By Ben Nadel on
Tags: ColdFusion

I was getting ready to answer an "Ask Ben" question, but I wanted to get a few facts nailed down before I proceeded. In particular, I wanted to double check on how scoped values could be referenced via the CALLER scope of ColdFusion custom tags. Often times, when dealing with ColdFusion custom tags, the references I used in CALLER are either non-scoped (assumed to be in the VARIABLES scope of the calling page) or use a variable name passed into the custom tag itself.

Here, I just wanted to see how referencing scoped variables would interact with the CALLER scope. So, I set up this simple index.cfm ColdFusion page that sets a "Value" into a few different scopes:

  • <!--- Set a value into various scopes. --->
  • <cfset REQUEST.Value = "From Request Scope" />
  • <cfset VARIABLES.Value = "From Variables Scope" />
  • <cfset COOKIE.Value = "From Cookie Scope" />
  •  
  • <!--- Test caller references. --->
  • <cf_testcaller />

Then, I set up a really simple ColdFusion custom tag, testcaller.cfm, that simply echoes out these variables by referring to them via the CALLER scope. Now, a long time ago, I discovered that the CALLER scope uses special key values that act differently than any standard ColdFusion structs, so this should be no surprise; but, I just wanted to formally review that this is all good and well:

  • <cfoutput>
  •  
  • <p>
  • Dot Notation:
  • </p>
  •  
  • <p>
  • REQUEST .... #CALLER.REQUEST.Value#<br />
  • VARIABLES .... #CALLER.VARIABLES.Value#<br />
  • COOKIE .... #CALLER.COOKIE.Value#<br />
  • </p>
  •  
  • <p>
  • Array Notation:
  • </p>
  •  
  • <p>
  • REQUEST .... #CALLER[ "REQUEST.Value" ]#<br />
  • VARIABLES .... #CALLER[ "VARIABLES.Value" ]#<br />
  • COOKIE .... #CALLER[ "COOKIE.Value" ]#<br />
  • </p>
  •  
  • </cfoutput>
  •  
  •  
  • <!--- Exit out of tag. --->
  • <cfexit method="exittag" />

Notice that we are testing the full dot-notation starting with the CALLER scope and, we are using the entire struct path of the target variable when using the array notation. Running the tag, we get the expected output:

Dot Notation:

REQUEST .... From Request Scope
VARIABLES .... From Variables Scope
COOKIE .... From Cookie Scope

Array Notation:

REQUEST .... From Request Scope
VARIABLES .... From Variables Scope
COOKIE .... From Cookie Scope

Now, just a reminder that this only works with proper variable names. You can't try to do something like this:

  • CALLER[ "REQUEST[ 'Value' ]" ]

... even though this is merely an alternate way to reference the REQUEST-scope Value variable.

Not a whole lot going on here; I just wanted to put this up here so I could refer to it later.




Reader Comments

Hmm. That seems shady to me. What if I do this?

cfset Variables["Request.Value"] = "From Variables Scope"

Then try to read it?

#Caller["Request.Value"]#

Logically, I should then get "From Variables Scope" instead of "From Request Scope", right?

Long story short, coding to count on that behavior seems iffy. And, logically, Caller.Cookie is just Cookie, and Caller.Request is just Request, as the thread should share the Cookie and Request scopes. Or are you trying to do something sneakier?

Reply to this Comment

Do you realize that it is a felony offense to use the term "Active Release Technique" (ART), or its likeness, without permission from Dr. Michael Leahy of Colorado Springs, CO? It is a patented technique, and they have/will prosecute. I thought that I might warn you.

Reply to this Comment

@Rick,

Good point on the ambiguous and conflicting variable name access. As far as the fact that CALLER.REQUEST is the same thing as REQUEST, this is true; however, I was setting this up for something a bit more dynamic in which the scope / structure being referenced might not be built-in one. I just used those because it seemed easy to test.

As far as good or bad for programming to this usage, I am not sure I can say one way or the other. Clearly, it doesn't work within the REQUEST scope itself which means that CALLER is not the exact same beast. I don't think that is an issue. CALLER has its own set of rules and behaviors. Unless Adobe says that this is a bug, which I don't think they have, I can't see anything wrong with leveraging it.

Of course, the cleaner, less ambiguous way would probably be to just use the dynamic naming convention:

<cfset "CALLER.#DynamicName#" = "Some Value" />

The problem is, this only works with Setting, not Getting. In fact, I don't think there is a way to actually reference a variable reference without using the CALLER[] notation. Perhaps that is why CALLER is designed to work this way.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.