another one is the safe navigation operator, which...
# lucee
z
another one is the safe navigation operator, which can be combined with elvis to start an entire new genre of music
Copy code
var prop = some?.key?.that?.is?.not?.there ?: "I'm a default value!";
https://docs.lucee.org/guides/developing-with-lucee-server/operators.html#safe-navigation-operator
🎉 1
👍 1
b
I thought Lucee had the safe nav operator ages ago?
pairing elvis with safe nav is pointless BTW. There is not effective difference whether you use safe nav or not. As soon as you slap elvis on the end, it behaves the same https://trycf.com/gist/c62f350c243a3f9df3d46db4e3ab68ca/lucee5?theme=monokai
The only reason IMO to ever use safe nav is if you want an actual null value back.
z
yeah it's ancient but it was pointed put that it wasn't documented
b
ahh, cool. Docs it is
It's honestly hard for me to ever find real life use cases for it. I rarely ever want null back from an expression. Most people use it with elvis, which like I said, makes it pointless.
FWIW, you didn't document that safe nav works on any dot access including method calls
Copy code
foo = "foo"

writedump( foo.toUpperCase() )                     // FOO
writedump( foo?.toBradCase() ?: "just kidding" )   // just kidding
most people forget that
Boxlang and Adobe all do it too
b
🎉 1
Dang, Adobe crashes and burns here
Copy code
foo = "foo"

writedump( foo?.bar ?: "default" )
Lucee and Boxlang both work fine, but Adobe complains about treating trying to dereference a key on a string
They must implement the safe nav at the struct level as opposed to the language construct
z
topic fucking, when you arriving in munich?
b
Tue, May 20 @ 6:55am
I'll have a day to shake off the jet lag, then our workshop the next
Looking forward to seeing everyone
z
i'll be there early wednesday afternoon, subject to the whims of German highspeed trains at 300km/h
👍 1
b
Thanks, @zackster, for the hilarious code sample. There are legitimate use-cases that could combine safe-navigation with the Elvis operator. Elvis performed at Westgate Hotel, formerly International, Las Vegas.
// Newsflash
if (rand() gt 0.5) {
LasVegasWestgateHotel.penthouseSuite.ElvisLounge.confirmedSighting="Elvis is in the building!";
} else {
LasVegasWestgateHotel.penthouseSuite.ElvisLounge.unConfirmedLocation=true;
}
writeoutput(LasVegasWestgateHotel?.penthouseSuite?.ElvisLounge?.confirmedSighting?:"Elvis has left the building!");
b
@BK BK To be clear, like I said above, safe nav is not required in your example. Removing it provides the exact same behavior since the elvis operator basically automatically applies safe dereferencing to the expression on the left hand side.
Copy code
LasVegasWestgateHotel.penthouseSuite.ElvisLounge.confirmedSighting ?: "Elvis has left the building!"
☝️ behaves just the same
I don't know how Lucee does it under the covers, but in BoxLang, we literally generate the same bytecode. Elvis just flips the
safe
flag in our AST for all "access" nodes on its left hand side, which is the same flag that the safe nav operator flips.
z
I've also seen a lot of Elvis usage which screams code smell and has caused innumerable bugs!
b
If you're on Adobe, all elvis usage is a bug, lol
z
We recently addressed property defaults only accepting and casting everything to strings
https://luceeserver.atlassian.net/browse/LDEV-801 another long standing cfml short coming addressed in 7
b
Oh, just realized I missed a button when pasting the code here. The full code is:
<p><button onclick="window.location.reload();">NewsFlash</button></p>
<cfscript>
if (rand() gt 0.5) {
LasVegasWestgateHotel.penthouseSuite.ElvisLounge.confirmedSighting="Elvis is in the building!";
} else {
LasVegasWestgateHotel.penthouseSuite.ElvisLounge.unConfirmedLocation=true;
}
writeoutput(LasVegasWestgateHotel?.penthouseSuite?.ElvisLounge?.confirmedSighting?:"Elvis has left the building!");
</cfscript>
@bdw429s, I got your point the first time. I don't know why you emphasize that two lines of code have the same behaviour. So what?
b
Well, perhaps you were just joking around, I honestly couldn't tell. You said you had a "legitimate use-case" for safe nav, and then shared code which was not, in fact, a legitimate use for it.
CF'ers are already confused enough about when to use it, I didn't want someone reading this thread to think it was neccessary
b
I wonder what your grounds are to say the use-case is not legitimate. I do think it is. Anyway, the code you give, `LasVegasWestgateHotel.penthouseSuite.ElvisLounge.confirmedSighting ?: "Elvis has left the building!`" does not reproduce completely the behaviour of my code.
b
The grounds are if you run both examples, they produce the same exact output, lol
What difference are you seeing?
To simplify the example
Copy code
foo={}
dump( foo?.bar ?: "default" )  // default
dump( foo.bar ?: "default" )  // default
both versions produce the same result
All dereferencing on the LHS of elvis is already made safe, regardless of whether you use safe nav
As I stated above, any expression with elvis at the end, doesn't need to use safe navigation.
b
I know how safe-navigation and Elvis work. We have no differences there. It's only now I see where we differ. Your last statement shows where you and I stand. You:
Copy code
any expression with elvis at the end, doesn't need to use safe navigation.
Me
Copy code
an expression with elvis at the end, may use safe navigation.
(the reason bring that "?." says something syntactically different from ".", which was a consideration in my use-case) Now that we understand each other, I hope we can agree to differ.
b
I guess 🙂 All I said is it's not necessary to use safe navigation in that scenario and people who think it offers some sort of runtime benefit are mistaken and typing it just to waste keystrokes.
If you like the readability of it or something, then I have no issue with you using it.
But it sounds like we agree that it does nothing and serves no functional purpose in conjunction with elvis
b
For the record, I do not share your opinion that typing the safe-navigation in that scenario is "just to waste keystrokes". I also do not think that using it "does nothing and serves no functional purpose in conjunction with elvis". End-result or output is not everything in software. Though
!!true
and
true
have the same end-result, you may use them to express different things. So, too,
foo?.bar ?: "default"
and
foo.bar ?: "default"
. For example, the safe-navigation question marks in
LasVegasWestgateHotel?.penthouseSuite?.ElvisLounge?.confirmedSighting?:"Elvis has left the building!"
, though redundant, help convey the idea of a search for the great man across the lobbies. Lucee, like every language known to humanity, has redundancy. Lots of it, for a reason. That enables you to express the same thing in different ways, depending on the meaning you wish to convey and on the way in which you wish to convey it. For example, you mention readability, which I wholeheartedly agree with.
👍 1