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 Scotch On The Rocks (SOTR) 2011 (Edinburgh) with:

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

By Ben Nadel on
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.



Looking For A New Job?

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

@Mark,

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

Reply to this Comment

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.

Reply to this Comment

@Justin,

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

Reply to this Comment

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.

Reply to this Comment

@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 :)

Reply to this Comment

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.

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.