In cfml how would someone match the string ‘false’...
# cfml-general
s
In cfml how would someone match the string ‘false’ ?
Copy code
value = 0;
value == 'false' //true
this is ending up matching as a falsey value
b
compareNoCase()
👍 1
s
is that not a bug?
m
I took a quick attempt and this Inline IF function may work or you. Looks a bit syntaxy but allows for it to be a singular variable and makes sure the string is numeric.
Copy code
IsFalseString = IIF( IsSimpleValue( InputString ) && !IsNumeric( inputString ) && InputString EQ targetString,DE( true ),DE( false ) );
j
You should be careful with your IIF usage as it runs an Evaluate on the arguments ( https://foundeo.com/security/guide/iif/ ).
m
Dually noted! Yeah evaluate is scary. Only ever use with explicit variables.
b
is that not a bug?
@Scott Steinbeck No, CFML has always treated 0 as falsey and all other integers as truthy.
Which is why, if you want to see if a string is the letters "f", "a", "l", "s", and "e" in that order, you should use
compareNoCase()
s
I assumed that was true of the Boolean, false but not the string ‘false’
b
You talk like there is a difference, lol
Any time CFML compares values, it will cast as necessary. **
** except for Lucee and two dates in strings
How else do you think
Copy code
"2" + "3" // 5
works in CFML
It's not like CF throws up its hands and says, "Oh geez, these are strings, I simply don't know how to add them!" 🙂
s
Well with math I assumed corrosion happened, but with comparison I imagined it would compare types first. I guess that is where a proper === would fit nicely
b
But you're still assuming you can "know" the underlying type.
Both
Copy code
isBoolean( 'false' )
and
Copy code
isBoolean( false )
return true!
CFML will never tell you what type a variable is, only what type it can be used as.
s
It was comparing 0 == ‘false’
b
Now, if you declared the variable yourself, you may know, but that's not the sort of information I ever write my code to care about if possible
Right, I know what your code was. But that's not a real use case. In a real use case, the variables are coming in from a function argument or something and you don't really know what's in them. And my further point is, you shouldn't care.
Here is Lucee's code that compares two values. Note this is a long rabbit trail of finding every possible imaginable combination of data/casting that can be done https://github.com/lucee/Lucee/blob/d70cb282abc20fa700d63e24f6ac815100ff4de6/core/src/main/java/lucee/runtime/op/OpUtil.java#L70
Here, for example, is the logic that eventually fires if both objects are a string. If at least one of them can be cast to boolean, then Lucee attempts to cast the other one to a boolean and compare them that way https://github.com/lucee/Lucee/blob/d70cb282abc20fa700d63e24f6ac815100ff4de6/core/src/main/java/lucee/runtime/op/OpUtil.java#L348
s
it stemmed from a real use case. I needed to uppercase all values in a query that matched ‘true’ or ‘false’. And it incorrectly converted 0/1 to TRUE/FALSE
b
Right, but I gave you the answer in my first reply
If you want to force a string comparison, then you use
compare()
or
compareNoCase()
. That's how CF works. All other
==
or
EQ
operators will use the class above which will allow for any loose typing match it can find.
👍 1
s
So I’m curious would the === be able to work in CF checking types and values? I want to say Zach mentioned that was going to work in 6
b
Well, Lucee already has a
===
but it's dumb (does a strict
==
check in Java) and everyone who uses it, does so on accident, lol
Adobe CF finally added a
===
like JS so Lucee 6 will FINALLY match it
But my professional opinion is there's never really a good reason to use it. At least not in a loosely typed language.
s
That’s fair, I realize it’s a minor downside for the benefits of a loosely typed language
b
If you've written code that cares about the type, I think you're generally working against the language.
For example, if there is a library which accepts a boolean flag to enable a feature, as a CFML dev, I have a reasonable expectation that I can pass any of the following values • true • "true" • "TrUe" • 1 • "yes" • 54290 and the feature darn well better be enabled
I would be a little put out if the dev ONLY accepted a boolean. That's not how CF works.
💯 1
s
For me this one seemed more like an unexpected gotcha. The rest of the truthy nature makes sense in my mind
👍 1
b
I generally see devs doing something like
Copy code
if( mySetting === true )
as though they've done the world some favor by being more pedantic in what they accept 🙂
🙃 1
d
See this related issue from 2014(!), some pretty surprising stuff, in a sense. All those tests still return the same results now, w cf 2021. (The + sign at the end of one line in the demo code is a typo.)
b
Yeah, all the crazy possible date formats have been the achillies heel of auto-casting in CFML. Lucee will only auto-cast dates if at least one of the two operands being compared is already a "proper" date object. If both are just strings or numbers, Lucee won't do it. Though, from what Micha has said over the years, this was more for performance than anything.
b
Just to be clear, ColdFusion 2021's strict-equality-operator answers the original question (a point you've all touched upon). value = 0; writeoutput(value === 'false'); // NO