Status/Resolution/Reason: Needs Review//BugVerified
Reporter/Name(from Bugbase): Joe G. / ()
Created: 06/13/2019
Components: Language
Versions: 2018
Failure Type: Incorrectly functioning
Found In Build/Fixed In Build: 2016 hf 11 through 2018 current, trycf /
Priority/Frequency: Normal / All users will encounter
Locale/System: English / Linux All
Vote Count: 1
Problem Description:
Definition of Elvis from Adobe documentation
"In an expression, if the resultant value is not defined, then the object will be assigned to the left most part of the expression otherwise a default value (define at the right most part) will be assigned"
Steps to Reproduce:
{code:java}
var a = false;
WriteOutput(IsDefined("a")?a:"default")
WriteOutput("<br>")
WriteOutput(a?:"default")
WriteOutput("<br>")
{code}
Actual Result:
false
default
Expected Result:
false
false
Any Workarounds:
None
See CF-4028563
This was never a bug and never should have been changed.
While I agree with Adam that "null coalesce" and "binary ternary" are not the same thing, that's where the agreement ends.
The problem was not with CF. The problem is that Adam assumed that CF's implementation of ?: was binary ternary. It wasn't. It never was. It never should have been.
Groovy: ?: = binary ternary, but NULL and FALSEY both replace the value
Javascript binary ternary: || because short circuit replaces the values
Kotlin: ?: = NULL coalesce. As CF was.
You cannot use other languages to drive this decision, because first of all, if you look for the "Elvis" operator online, few people can agree on whether that operator is ?. or ?:
When the language defines an operator it should be for the use of THAT language. I can see great benefits to a null coalescing operator in Coldfusion, because it removes the need for <cfparam> while ALSO dealing with Nulls, which can be introduced by safe-nav ?. I can see little to no benefit for a binary ternary... Plain ternary is good enough, and if you actually want a binary ternary mechanism, implement || (which can also be used for logic reasons.
To wit, it is absolutely unacceptable that the documentation says:
"In an expression, if the resultant value is not defined, then the object will be assigned to the left most part of the expression otherwise a default value (define at the right most part) will be assigned"
(Note it says ABSOLUTELY NOTHING about whether the value is true or valse)
However,
var a = false;
IsDefined("a")?a:"default"
Returns false, but
a?:"default"
Returns "default"
Which means your "bugfix" has violated the specification of the feature and never should have been done.
Attachments:
Comments: