An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

isDefined() vs structKeyExists()

July 14, 2004 ·

Which should you use? If you're using CFMX then all scopes are structs and you will be much safer with structKeyExists(scopeName,"varName"). Depending on your JVM, it may also be faster than isDefined("scopeName.varName").
isDefined() tries very hard to find any possible definition of the requested variable. It searches through the scopes as if the variable name is not scope-qualified - even when it contains a dot (.) which seems to date back to pre-MX ColdFusion which allowed dots in variable names. For example, if you say:
<cfset variables.variables.foo = 42 />
you may be surprised to discover that isDefined("variables.foo") is YES, even tho' there is no variable called foo in the variables scope. If you say isDefined("foo") and foo is a URL scope variable, you'll get YES (unqualified scope lookup) but if you say isDefined("x.foo") you'll get NO even if x.foo is passed in the URL - you need isDefined("url.x.foo") for that. Buggy? Perhaps. Confusing? Certainly!
In all cases, structKeyExists() lets you test for variable existence much more precisely:
structKeyExists(variables,"foo") is NO
structKeyExists(variables,"variables") is YES
structKeyExists(variables.variables,"foo") is YES
(for the examples above).

Tags: coldfusion

33 responses

  • 1 Ryan Guill // Sep 8, 2004 at 5:04 PM

    so, is there any plans to rectify this &quot;bug&quot; in future versions, or should we concede to using structkeyexists() for all of our isDefined() needs? thats a lot of code to rework, although i never ask if a variable is defined that could be questionable, the speed issue is one thing to consider.
  • 2 Giampaolo Bellavite // Sep 8, 2004 at 5:04 PM

    And what about the arguments scope? In my CFCs I noticed I have to use isDefined('arguments.myArg') instead of structKeyExists(arguments, 'myArg'): sometimes structKeyExists doesn't work for me.
  • 3 Sean Corfield // Sep 8, 2004 at 5:04 PM

    I've never had to use isDefined() with arguments. Can you provide a concrete example that shows the problem?
  • 4 PaulKD // Sep 8, 2004 at 5:04 PM

    Sean,&lt;br /&gt;&lt;br /&gt;More of the same please.&lt;br /&gt;&lt;br /&gt;I've often wonder why I should &quot;choose one over the other&quot; with several CF tags, functions and techniques. I've rejected converting my if &quot;x&quot; is &quot;y&quot; to comparenocase on the grounds that the comparenocase logic does my head in and all the &quot;speed&quot; justification examples seem to be over 10,000 loops ;-)
  • 5 dgibson // Sep 8, 2004 at 5:04 PM

    I've never had a problem with isDefined. If you follow &quot;good practice&quot; by not naming structures the same as scope names, you will save yourself a lot more trouble than this particular &quot;bug&quot;.
  • 6 Larry // Sep 8, 2004 at 5:04 PM

    CFMX accepts and recognizes periods in variables. Therefore: &lt;br /&gt; works fine even if it is bad coding practice, and Isdefined(&quot;test.foo&quot;) or IsDefined(&quot;variables.test.foo&quot;) both return true as they should. StructKeyExist(variables,&quot;test.foo&quot;) incorrectly returns false.&lt;br /&gt;&lt;br /&gt;As for performance, why would Isdefined(&quot;Form.Field&quot;) search all scopes when I have specificly specified a valid CF scope (Form). I can understand if I do not include a valid scope why it would search them all, but there are times that may be a desired action.
  • 7 Sean Corfield // Sep 8, 2004 at 5:04 PM

    I've had some very specific problems with isDefined() accessing the CGI scope (because its argument was not defined in the variables scope or arguments scope) - accesses to the CGI scope can cause callbacks to the web server :(&lt;br /&gt;&lt;br /&gt;That's my main reason for avoiding isDefined() - the fine-grained control over which scope to search is important too, performance is secondary.
  • 8 Laurence // Sep 8, 2004 at 5:04 PM

    What are your thoughts on the isNotMap() function. I found this function in the Programming ColdFusion MX book by Rob Brooks-Bilson.
  • 9 Sean Corfield // Sep 8, 2004 at 5:04 PM

    I've never heard of that function Laurence...
  • 10 James Holmes // Sep 8, 2004 at 5:04 PM

    OK, here's the same thing escaped so that it actually shows up:&lt;br /&gt;&lt;br /&gt;&amp;lt;cfif IsDefined(&amp;quot;SESSION.Username&amp;quot;)&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;!---secure stuff here ---&amp;gt;&lt;br /&gt;&amp;lt;/cfif&amp;gt;
  • 11 David McLean // Aug 23, 2006 at 6:31 AM

    I think I discovered a 'good' bug if there is such a thing. I worked on resolving an issue with our site where a bit of wayward development resulted in a variable in the form scope was called 347TID which is syntactically incorrect as it begins with a numeric character. IsDefined throws an error declaring the issue with the naming of the variable, where as structKeyExists permits it and returns true or false. Not necessarily a vote in favour of isDefined, but definately something that needs fixing in structKeyExists???
  • 12 Sean Corfield // Aug 23, 2006 at 8:02 AM

    @David, no, that's exactly how ColdFusion is intended to work: you can put *any* key you like in a struct: form[&quot;347TID&quot;] and structKeyExists() must work with that.
  • 13 David McLean // Aug 23, 2006 at 8:26 AM

    Thanks.Is there any rationale for this? And what is the difference between 347TID being a syntactically incorrect variable name but at the same time being a permitted struct key? Is variables.347TID both a syntactically incorrect variable name and a permitted struct key at the same time? I am truly interested in understaning how and why this is the case. There's something similar to the Heisenberg uncertainty principle going on here ;-)
  • 14 Sean Corfield // Aug 23, 2006 at 10:26 AM

    @David, *anything* is a valid struct key - any string. That's basic ColdFusion stuff. It has nothing whatsoever to do with variable names. I'm not sure how to explain it any more clearly...
  • 15 David McLean // Aug 23, 2006 at 1:11 PM

    I understand *anything* can be a struct key. I didn't know that after 8 years of CF but hey I do now. What I don't understand is why this is the case for struct keys when it isn't the case for variables; I can't see any reason for this difference. Isn't a variable actually a key in the variables scope struct? Anyway no matter. I think we might be talking at cross purposes.
  • 16 Ryan Stewart // Oct 23, 2006 at 1:13 AM

    &quot;StructKeyExist(variables,&quot;test.foo&quot;)&quot;
    --
    Wouldn't this be written:
    StructKeyExist(variables.test,&quot;foo&quot;) ?
  • 17 Sean Corfield // Oct 23, 2006 at 7:44 AM

    @Ryan, I assume you're answering Larry's comment? Yes, isDefined(&quot;variables.test.foo&quot;) is technically equivalent to:

    structKeyExists(variables,&quot;test&quot;) and structKeyExists(variables.test,&quot;foo&quot;)

    You need both.
  • 18 William Broadhead // Apr 3, 2007 at 6:09 PM

    hum...okay, played around with that a bit more as our dev group is trying to decide what REALLY is best practise....

    Short answer: structKeyExists is SLOWER and has no advantage other than forcing coder to use scoping, which s/he should do anyway...

    Long Answer:

    whereas for the examples below url.pageid is a real url variable

    STRUCTKEYEXISTS:
    structKeyExists is pretty much the same speed no matter what you throw at it, keys can be real or not (url, 'pageid' and url, 'pageadfasdf' are about the same, no big diff one way or the other)
    and if you throw a scope at it that does not exist, it throws, so it forces you to be careful about scoping.

    ISDEFINED:
    isDefined is super fast when the scope exists and you pass in a scope (url.pageid),
    however, it is extremely extremely mega super slow when you pass in a non-existant scope (urlss.pageid).
    it is also super super mega slow if you pass in a non-scoped non-existant variable (pagelksjdljsdf)
    it is quite fast, on average 10 to 20% faster than structKeyExists, when you pass in a SCOPED variable, existant or not (url.pageid or url.aoiausldkjf)

    So what does that mean in real life?
    Well, as long as you are asking for a SCOPED variable that is extant, and you don't mispell the scope (url for instance), isDefined will be faster on average....
    If you are looking for a NON-SCOPED variable, you have no choice but to live with isDefined.... hum....which can be very very slow when the variable does not exist.
    If you want to make sure you scope all your vars, use structKeyExists and live with a small speed hit, but be assured it is scoped to a real scope (or throw an error).
    So for me, in real life use, that means isDefined is probably the better choice as it is overall going to be faster as long as i can spell my scope correctly.
    It also is the only choice to use when looking for multiple scope variables such as FORM.ID vs URL.ID and your page/function can take either and want to simply ask isDefined('ID')
    but if you want to prioritize one over the other (which you probably should) then you can again use either define/struct
    where you have a little bit of script that checks each (form.id and then url.id) and assigns a variables.myID which is then passed in to page/function to use....
    again, this would indicate isDefined would be preferred as it would be faster for that call too, as long as it is scoped and the scope exists.
    So I can't find any reason to use structKeyExists other than it might seem like better code because it forces scoping....
    How sad... it seemed like it should be faster as it specifies the scope....

    here is sample code for you to run and see for yourself.... i'd love to know if you find anything different than what I did by platform or other (I am using CFMX702 on a WINDOWS platform). Is linux version any faster? Anyone know what actually happens at the compiled java level?)

    &lt;CFSCRIPT&gt;
    ITERATIONS = 100000;
    writeoutput('ITERATIONS : ' &amp; ITERATIONS &amp; '&lt;BR&gt;' );
    i=0;
    j=0;
    k=0;
    ttt1 =0;
    ttt2 =0;
    t1c =0;
    t2c=0;

    for(k; k lte ITERATIONS; k=k+1){

    T1 = getTickCount();
    for(i; i lte ITERATIONS; i=i+1){
    if(isdefined('url.asdfpageid')){
    //do nothing
    }
    }
    T2 = getTickCount();
    TT1 = T2-T1;
    ttt1=ttt1+TT1;


    T3 = getTickCount();
    for(j; j lte ITERATIONS;j=j+1){
    if(structKeyExists(url, 'pageeid')){
    //do nothing
    }
    }
    T4 = getTickCount();
    TT2 = T4-T3;
    ttt2=ttt2+TT2;
    if(TT1 gt 0){t1c = t1c+1;}
    if(TT1 gt 0){t2c = t2c+1;}

    if(TT1 gt 0 or TT2 gt 0){writeoutput('Iteration K: ' &amp; k &amp; ' isDefined: ' &amp; TT1 &amp; 'ms'); writeoutput(' structKeyExists: ' &amp; TT2 &amp; 'ms&lt;br&gt;');}


    }

    writeoutput('&lt;BR&gt;Times isDefined used time: ' &amp; t1c);
    writeoutput('&lt;BR&gt;Times structKeyExists used time: ' &amp; t2c);

    writeoutput('&lt;BR&gt;FINAL isDefined: ' &amp; TTT1 &amp; 'ms');
    writeoutput('&lt;BR&gt;FINAL structKeyExists: ' &amp; TTT2 &amp; 'ms');

    &lt;/CFSCRIPT&gt;
    &lt;br&gt;



    &lt;!--- The cfchart ---&gt;
    &lt;cfchart format=&quot;flash&quot; xaxistitle=&quot;function&quot; yaxistitle=&quot;Loading Time&quot;&gt;
    &lt;cfchartseries type=&quot;bar&quot; serieslabel=&quot;isDefined&quot;&gt;
    &lt;cfchartdata item=&quot;isDefined&quot; value=&quot;#variables.TTT1#&quot;&gt;
    &lt;/cfchartseries&gt;
    &lt;cfchartseries type=&quot;bar&quot; serieslabel=&quot;structKeyExists&quot;&gt;
    &lt;cfchartdata item=&quot;structKeyExists&quot; value=&quot;#variables.TTT2#&quot;&gt;
    &lt;/cfchartseries&gt;
    &lt;/cfchart&gt;
  • 19 Sean Corfield // Apr 3, 2007 at 10:15 PM

    @William, I ran your code - repeatedly - and the results always showed structKeyExists() being 20-30% FASTER than isDefined() on an Intel-powered Mac.
  • 20 William Broadhead // Apr 4, 2007 at 1:12 PM

    That is very very interesting. I suspect people aren't making false claims about it really being faster without doing some testing. I was trusting it was, until I came across a British blog that said the contrary, so I ran my own tests to verify. Sure enough, on my windows XP Pro sp2 CoreDuo 6400 2.30 4gb ram IIS5.1 cmfx702 with debug on, isDefined IS consistently slower. I am going to run the same code on our live server (windoze 2003 web edition dual xeon 2.8 IIS6 2gb ram cfmx702) and see what happens. If this is the case, that it is an environment issue more than a function issue, that might also imply that general optimization of jrun on a linux envronment is better than the windows equivalent. I would actually love to find that coldfusion code (esp the best practise versions of various functions) is in fact faster in linux environments (and thus overall performance should be faster) as I had originally wanted to push for setting up our live in that environment and plan on moving towards that platform in the mid- to long term because of the windows ram limitation in their web edition.
  • 21 William Broadhead // Apr 4, 2007 at 2:34 PM

    hum.. running on live server (dual xeon 2.8ghz 2gb ram windows 2003 web edition server)

    2 sets of runs, 15 run throughs, not a single instance of structKeyExists as faster...

    i'll post the code and results in two following posts.
  • 22 William Broadhead // Apr 4, 2007 at 2:36 PM

    updated code:

    &lt;CFSCRIPT&gt;
       ITERATIONS = 1000000;
       writeoutput('ITERATIONS : ' &amp;    ITERATIONS &amp; '&lt;BR&gt;' );
       i=0;
       j=0;
       k=0;
       ttt1 =0;
       ttt2 =0;
       t1c =0;
       t2c=0;

       for(k; k lte ITERATIONS; k=k+1){

       T1 = getTickCount();
       for(i; i lte ITERATIONS; i=i+1){
          if(isdefined('url.pageid')){
          //do nothing
          }
       }
       T2 = getTickCount();
       TT1 = T2-T1;
       ttt1=ttt1+TT1;


       T3 = getTickCount();
       for(j; j lte ITERATIONS;j=j+1){
          if(structKeyExists(url, 'pageid')){
          //do nothing
          }
       }
       T4 = getTickCount();
       TT2 = T4-T3;
       ttt2=ttt2+TT2;
       if(TT1 gt 0){t1c = t1c+1;}
       if(TT2 gt 0){t2c = t2c+1;}

       if(TT1 gt 0 or TT2 gt 0){writeoutput('Iteration K: ' &amp; k &amp; ' isDefined: ' &amp; TT1 &amp; 'ms'); writeoutput(' structKeyExists: ' &amp; TT2 &amp; 'ms&lt;br&gt;');}


       }

       writeoutput('&lt;BR&gt;Times isDefined used time: ' &amp; t1c);
       writeoutput('&lt;BR&gt;Times structKeyExists used time: ' &amp; t2c);

       writeoutput('&lt;BR&gt;FINAL isDefined: ' &amp; TTT1 &amp; 'ms');
       writeoutput('&lt;BR&gt;FINAL structKeyExists: ' &amp; TTT2 &amp; 'ms');

       if(TTT1 GT TTT2){
          writeoutput('&lt;BR&gt;structKeyExists is faster by: ' &amp; TTT1-TTT2 &amp; 'ms which is ' &amp; NUMBERFORMAT((TTT1-TTT2)/TTT1*100, '9.9') &amp; '% faster');
       }else{
          writeoutput('&lt;BR&gt;isDefined is faster by: ' &amp; TTT2-TTT1 &amp; 'ms which is ' &amp; NUMBERFORMAT((TTT2-TTT1)/TTT2*100, '9.9') &amp; '% faster' );
       }

    &lt;/CFSCRIPT&gt;


    &lt;br&gt;



    &lt;!--- The cfchart ---&gt;
    &lt;cfchart format=&quot;flash&quot; xaxistitle=&quot;function&quot; yaxistitle=&quot;Loading Time&quot;&gt;
       &lt;cfchartseries type=&quot;bar&quot; serieslabel=&quot;isDefined&quot;&gt;
       &lt;cfchartdata item=&quot;isDefined&quot; value=&quot;#variables.TTT1#&quot;&gt;
       &lt;/cfchartseries&gt;
       &lt;cfchartseries type=&quot;bar&quot; serieslabel=&quot;structKeyExists&quot;&gt;
       &lt;cfchartdata item=&quot;structKeyExists&quot; value=&quot;#variables.TTT2#&quot;&gt;
       &lt;/cfchartseries&gt;
    &lt;/cfchart&gt;




  • 23 William Broadhead // Apr 4, 2007 at 2:37 PM

    15 runs where scope exists, but key does not (url.pageid) with 1,000,000 iterations of 2 sets of 1,000,000 calls

    Times isDefined used time: 107
    Times structKeyExists used time: 118
    FINAL isDefined: 4925ms
    FINAL structKeyExists: 5641ms
    isDefined is faster by: 716ms which is 12.7% faster

    Times isDefined used time: 123
    Times structKeyExists used time: 136
    FINAL isDefined: 5255ms
    FINAL structKeyExists: 5626ms
    isDefined is faster by: 371ms which is 6.6% faster

    Times isDefined used time: 104
    Times structKeyExists used time: 138
    FINAL isDefined: 5792ms
    FINAL structKeyExists: 6002ms
    isDefined is faster by: 210ms which is 3.5% faster

    Times isDefined used time: 148
    Times structKeyExists used time: 150
    FINAL isDefined: 6221ms
    FINAL structKeyExists: 6375ms
    isDefined is faster by: 154ms which is 2.4% faster

    Times isDefined used time: 349
    Times structKeyExists used time: 318
    FINAL isDefined: 21747ms
    FINAL structKeyExists: 23098ms
    isDefined is faster by: 1351ms which is 5.8% faster

    Times isDefined used time: 271
    Times structKeyExists used time: 325
    FINAL isDefined: 14802ms
    FINAL structKeyExists: 31557ms
    isDefined is faster by: 16755ms which is 53.1% faster

    Times isDefined used time: 300
    Times structKeyExists used time: 293
    FINAL isDefined: 25496ms
    FINAL structKeyExists: 35296ms
    isDefined is faster by: 9800ms which is 27.8% faster

    Times isDefined used time: 333
    Times structKeyExists used time: 271
    FINAL isDefined: 22676ms
    FINAL structKeyExists: 26463ms
    isDefined is faster by: 3787ms which is 14.3% faster

    Times isDefined used time: 245
    Times structKeyExists used time: 268
    FINAL isDefined: 11288ms
    FINAL structKeyExists: 15934ms
    isDefined is faster by: 4646ms which is 29.2% faster

    Times isDefined used time: 220
    Times structKeyExists used time: 267
    FINAL isDefined: 11470ms
    FINAL structKeyExists: 16012ms
    isDefined is faster by: 4542ms which is 28.4% faster

    Times isDefined used time: 266
    Times structKeyExists used time: 281
    FINAL isDefined: 10572ms
    FINAL structKeyExists: 13946ms
    isDefined is faster by: 3374ms which is 24.2% faster

    Times isDefined used time: 278
    Times structKeyExists used time: 275
    FINAL isDefined: 10125ms
    FINAL structKeyExists: 13329ms
    isDefined is faster by: 3204ms which is 24.0% faster

    Times isDefined used time: 242
    Times structKeyExists used time: 253
    FINAL isDefined: 10067ms
    FINAL structKeyExists: 14494ms
    isDefined is faster by: 4427ms which is 30.5% faster

    Times isDefined used time: 192
    Times structKeyExists used time: 221
    FINAL isDefined: 7526ms
    FINAL structKeyExists: 12226ms
    isDefined is faster by: 4700ms which is 38.4% faster





    Hum...on my random pulls, i usually see about 1 in 10 where structKeyExists is faster, but this particular series (ran in 5 windows 3 times each concurrently, thus under some load), I didn't get any...


    15 pulls where scope and key exist.

    Times isDefined used time: 312
    Times structKeyExists used time: 317
    FINAL isDefined: 7706ms
    FINAL structKeyExists: 8730ms
    isDefined is faster by: 1024ms which is 11.7% faster

    Times isDefined used time: 311
    Times structKeyExists used time: 338
    FINAL isDefined: 8596ms
    FINAL structKeyExists: 17218ms
    isDefined is faster by: 8622ms which is 50.1% faster

    Times isDefined used time: 326
    Times structKeyExists used time: 314
    FINAL isDefined: 12959ms
    FINAL structKeyExists: 16560ms
    isDefined is faster by: 3601ms which is 21.7% faster

    Times isDefined used time: 301
    Times structKeyExists used time: 275
    FINAL isDefined: 12339ms
    FINAL structKeyExists: 16680ms
    isDefined is faster by: 4341ms which is 26.0% faster

    Times isDefined used time: 298
    Times structKeyExists used time: 322
    FINAL isDefined: 12346ms
    FINAL structKeyExists: 17918ms
    isDefined is faster by: 5572ms which is 31.1% faster

    Times isDefined used time: 350
    Times structKeyExists used time: 347
    FINAL isDefined: 12619ms
    FINAL structKeyExists: 17863ms
    isDefined is faster by: 5244ms which is 29.4% faster

    Times isDefined used time: 358
    Times structKeyExists used time: 331
    FINAL isDefined: 12248ms
    FINAL structKeyExists: 18148ms
    isDefined is faster by: 5900ms which is 32.5% faster

    Times isDefined used time: 374
    Times structKeyExists used time: 363
    FINAL isDefined: 9712ms
    FINAL structKeyExists: 12739ms
    isDefined is faster by: 3027ms which is 23.8% faster

    Times isDefined used time: 320
    Times structKeyExists used time: 355
    FINAL isDefined: 15134ms
    FINAL structKeyExists: 19300ms
    isDefined is faster by: 4166ms which is 21.6% faster

    Times isDefined used time: 314
    Times structKeyExists used time: 324
    FINAL isDefined: 14377ms
    FINAL structKeyExists: 19059ms
    isDefined is faster by: 4682ms which is 24.6% faster

    Times isDefined used time: 291
    Times structKeyExists used time: 349
    FINAL isDefined: 13776ms
    FINAL structKeyExists: 21890ms
    isDefined is faster by: 8114ms which is 37.1% faster

    Times isDefined used time: 360
    Times structKeyExists used time: 351
    FINAL isDefined: 13814ms
    FINAL structKeyExists: 23769ms
    isDefined is faster by: 9955ms which is 41.9% faster

    Times isDefined used time: 244
    Times structKeyExists used time: 247
    FINAL isDefined: 9884ms
    FINAL structKeyExists: 14090ms
    isDefined is faster by: 4206ms which is 29.9% faster

    Times isDefined used time: 293
    Times structKeyExists used time: 266
    FINAL isDefined: 9830ms
    FINAL structKeyExists: 13967ms
    isDefined is faster by: 4137ms which is 29.6% faster

    Times isDefined used time: 312
    Times structKeyExists used time: 315
    FINAL isDefined: 8854ms
    FINAL structKeyExists: 11584ms
    isDefined is faster by: 2730ms which is 23.6% faster


    hum... well... not sure what to say. even worse than what i get on my development machine.

  • 24 Sean Corfield // Apr 4, 2007 at 3:25 PM

    I ran it multiple times. structKeyExists() was ALWAYS faster. The closest margin was 5.5%. More typically, structKeyExists() was around 15-20% faster on this latest code. Example run:

    Times isDefined used time: 786
    Times structKeyExists used time: 746
    FINAL isDefined: 2278ms
    FINAL structKeyExists: 1790ms
    structKeyExists is faster by: 488ms which is 21.4% faster
  • 25 Jake Astle // Apr 4, 2007 at 4:17 PM

    I would have to agree with William I get the same results as he does. The few that structKeyExits is faster it is a very small margin yet when is defined is faster it is by a fair amount.
  • 26 Jeff Gladnick // Apr 20, 2009 at 11:30 AM

    I also get the same result as william and was surprised to see the isdefined was faster. I just did a basic look 10,000 times with a cfif structKeyexists / isdefined in it.
  • 27 Sean Corfield // Apr 20, 2009 at 11:54 AM

    @Jeff, @William, @Jake - it must be due to JVM differences then. A good reason why low-level code optimizations are unreliable (and generally not worth the effort).

    As I said in several places, I've had specific problems with isDefined() so I avoid it - except in the one case where I've needed it: for testing against null in the result of a method call:

    var res = obj.someMethod(args);

    if ( isDefined('res') ) ...

    Currently there's no other way to test for null results (in ColdFusion, at least).
  • 28 Mark // May 6, 2009 at 5:56 PM

    So why would this:

    &lt;cffunction name=&quot;onRequest&quot; returntype=&quot;boolean&quot;&gt;
          &lt;cfargument name=&quot;targetPage&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;
    &lt;cfif isUserLoggedIn()&gt;
       &lt;cfif not structKeyExists(session,&quot;user&quot;)&gt;
       &lt;!--- do something ---&gt;
    &lt;cfinclude template=&quot;test.cfm&quot;&gt;
    &lt;cfelse&gt;
                &lt;cfinclude template=&quot;#arguments.targetPage#&quot;&gt;
    &lt;/cfif&gt;
    &lt;/cfif&gt;
    &lt;cfreturn true /&gt;
    &lt;/cffunction&gt;

    behave so differently from this:

    &lt;cffunction name=&quot;onRequest&quot; returntype=&quot;boolean&quot;&gt;
          &lt;cfargument name=&quot;targetPage&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;
    &lt;cfif isUserLoggedIn()&gt;
       &lt;cfif not isDefined(session.user)&gt;
       &lt;!--- do something ---&gt;
    &lt;cfinclude template=&quot;test.cfm&quot;&gt;
    &lt;cfelse&gt;
                &lt;cfinclude template=&quot;#arguments.targetPage#&quot;&gt;
    &lt;/cfif&gt;
    &lt;/cfif&gt;
    &lt;cfreturn true /&gt;
    &lt;/cffunction&gt;
  • 29 Sean Corfield // May 6, 2009 at 6:05 PM

    @Mark, first, I assume you mean isDefined(&quot;session.user&quot;) - with quotes?

    Second, you don't say how those two pieces of code behave &quot;so differently&quot; so it is hard to tell what you're asking...
  • 30 Eapen // Sep 8, 2010 at 2:50 AM

    @Sean

    I want to test if a struct key exists in another struct key that may or may not exist.

    i.e.
    I want to test for variables.variablesS.test
    but variables.variablesS may or may not exist.

    Just wanted to find out if there is an easier way to do this? (where variables.variablesS does not exist)

    With IsDefined, I could do
    IsDefined("variables.variablesS.test")

    but with structKeyExists, I would have to do:
    StructKeyExists(variables, "variablesS") AND StructKeyExists(variables.variablesS, "test").

    Is there an easier way to do this - since we can't do the following:

    StructKeyExists(variables, "variablesS.test")
  • 31 jfrobishow // Nov 10, 2010 at 1:53 PM

    @Eapen

    Try (I didn't test it, but it make sense in my head :P)
    StructKeyExists(variables["variablesS"], "test")
  • 32 Sean Corfield // Nov 10, 2010 at 3:01 PM

    @jfrobishow, that will fail when variables.variablesS does not exist.

    Also variables["variablesS"] is equivalent to variables.variablesS anyway.
  • 33 jfrobishow // Nov 10, 2010 at 3:05 PM

    @Sean,

    Ah got me there, I knew I should have tested that before posting, hehe ;)