Example of Breaking Change
This code runs differently in CF11 and CF2016:
foo = 0; result = foo ?: 'default'; // CF11: result == 0 // CF2016: result == 'default'
But this is apparently not a bug and is in fact the result of a bug fix.
ColdFusion 11 gives us a null coalescing operator!
In CF11, Adobe introduced the Elvis operator (?:
). It worked as a form of null coalescing operator. CFML doesn’t really have null
values and where they do exist they tend to be treated as undefined
, so the Elvis operator ended up being more of an undefined coalescing operator.
It’d probably be easiest to show how it worked in code. These two examples were basically equivalent:
// Ternary foo = isDefined('bar') ? bar : 'default value'; // Elvis operator foo = bar ?: 'default value';
For a more thorough breakdown of CF11’s Elvis operator behavior check out Ben Nadel’s article.
ColdFusion 2016 takes away the null coalescing operator!
Someone noticed that the Elvis operator is not typically used as a null coalescing operator in other languages. It is instead used as a sort of “binary ternary” shorthand. Example:
// Elvis operator in other languages foo = bar ?: 'default value'; // Would be (mostly) equivalent to this: foo = bar ? bar : 'default value';
The main difference is now if the left hand side is falsy (not just null or undefined) then the right hand side is returned.
Suitably embarrassed, the CF devs fixed the Elvis operator to work as other languages work. The only problem is we now have an undocumented breaking change between CF11 and CF2016. Oh, and that neat null coalescing operator? Yeah it’s just gone.