ColdFusion 9's IsNull() Works On Non-Struct Objects

Posted December 28, 2010 at 9:17 AM by Ben Nadel

Tags: ColdFusion

When I first did my exploration of ColdFusion 9's isNull() function, I definitely came away thinking that the isNull() function was merely a short-hand, convenience notation for the existing structKeyExists() function. The other day, however, when blogging about creating proxy objects, I was dealing with a situation in which the base value that I was checking might not always be an object with a struct-like interface. In a scenario like that, my first instinct was to check for "struct-ness" before I checked for "null-ness:"

  • <cfif (
  • isStruct( someValue ) &&
  • !isNull( someValue.someKey )
  • )>
  •  
  • <!--- Do some conditional logic here... --->
  •  
  • </cfif>

As you can see here, I'm using the short-circuiting nature of ColdFusion's conditional statements in order to check that the value was both a struct and that a key off of that struct was non-null. On a whim, I decided to see if I could remove the isStruct() condition. And, much to my delight, it turns out that isNull() works on simple values just as well as it works on structs.

  • <!--- Create a string value. --->
  • <cfset myString = "Boo ya!" />
  •  
  • <!--- Check for a property of it. --->
  • String Key Null: #isNull( myString.someKey )#

As you can see, we are checking for a property of a string value (which is typically a no-no in ColdFusion). When we run the above code, we get the following output:

String Key Null: YES

It correctly determines that the given key path cannot be gotten off of the given base value. It doesn't matter at all that the base value is a simple value and not a struct (or struct-like object).

Now, like I said, it was sort of my assumption that isNull() was a short-hand for structKeyExists(); however, if we try to rewrite the previous statement using structKeyExists():

  • <!--- Create a string value. --->
  • <cfset myString = "Boo ya!" />
  •  
  • <!--- Check for a property of it. --->
  • String Key Exists: #structKeyExists( myString, "someKey" )#

... we get the following ColdFusion error:

You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.

As you can see, when we explicitly treat the string as a struct, we get an error; but, if we let isNull() do the key-path checking, the data type doesn't matter.

I know this is a really minor point, but if you think that isNull() is nothing more than a short-hand for structKeyExists() - just as I sort of did - then you really aren't leveraging isNull() to its full potential. ColdFusion 9's isNull() function allows you essentially confirm both data type and key path existence within a single conditional statement.




Reader Comments

Dec 28, 2010 at 9:29 AM // reply »
4 Comments

Ben,

I love nuances like this one. Thanks for teasing it out. I had the same take that you did.

-Mark


Dec 28, 2010 at 9:47 AM // reply »
11,246 Comments

@Mark,

Heck yeah - it's all about understanding what the language can really do ... and leveraging it :)


Dec 28, 2010 at 12:25 PM // reply »
2 Comments

Is this a new behavior in CF9 or has it existed previously? I'd love to use this instead of StructKeyExists(), but can't if it's not backwards compatible.


Dec 28, 2010 at 2:02 PM // reply »
11,246 Comments

@Justin,

The isNull() function is new in CF9. For CF8, you have to use structKeyExists() or isDefined().


Dec 28, 2010 at 2:44 PM // reply »
272 Comments

For what it's worth, I use IsDefined("struct1.struct2.struct3.key") all the time without first checking struct1, struct2 or struct3. I can't recall ever using StructKeyExists. But then, that's just me. StructKeyExists probably compiles to much more efficient Java.


Dec 28, 2010 at 3:09 PM // reply »
11,246 Comments

@WebManWalking,

To be honest, I don't use isDefined() enough to know the rules behind it. That's cool that you can use arbitrary data types as well. I know there are some differences between isNull() and isDefined(), specifically when checking for scope existence:

http://www.bennadel.com/blog/1773-IsNull-vs-IsDefined-For-ColdFusion-9-Scope-Detection.htm

It seems that isNull() isn't quite like structKeyExists() and it isn't quite like isDefined(). It's some magical beast unto itself :)


Dec 29, 2010 at 5:04 AM // reply »
272 Comments

You know how Evaluate() translates a string (with possible #-sign substitutions if it's a string literal) into a variable reference, right? Well basically, for any string, if IsDefined(string) is true, Evaluate(string) will not crash.

In the IsDefined("struct1.struct2.struct3.key") example, I don't really care why it failed: struct1 may not exist, or struct1 may not be a struct, or struct1.struct2 might not exist, etc, etc. All of those possibilities result in the IsDefined() call returning false.

I think you've hit on something with IsNull(). It's sort of similar to a Java HashMap or TreeMap. If you try to get() a key you never put(), the get() returns false. It's like IsDefined("ref") with quotes is equivalent to IsNull(ref) without quotes.


Dec 29, 2010 at 5:07 AM // reply »
272 Comments

I should have said, if you try to get() a key you never put(), the get() returns null.


Dec 29, 2010 at 9:37 AM // reply »
11,246 Comments

@WebManWalking,

Exactly... except for scope evaluation.


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 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
May 23, 2013 at 11:06 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Are you talking about As Number: YES As String: YES As Java: YES? If so, that's with 3 different ways of referencing the constant 1, not users.id[1]. Query object references(*) are what seem ... read »
May 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
May 23, 2013 at 9:47 AM
ColdFusion QueryAppend( qOne, qTwo )
You rock! Thank you, thank you, thank you!!! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools