isDefined; structure with a numeric key

Hi @Zackster,

Oh… this explains that.

Thank you for the info!

check out these options instead

3 Likes

Interesting! I’ll keep it in mind. Thank you!

This should not encourage you to use isdefined(), but for structs you can still always use the bracket notation as a working solution. Just to complete all the alternatives here:

<cfset myStructure = structNew()>
<cfset myStructure["1"] = "Hello there">

<cfdump var="#myStructure#" label="myStructure">

<cfif isDefined("myStructure['1']")>
    The variable myStructure.1 is defined
<cfelse>
    The variable myStructure.1 is not defined <!--- It returns is not defined --->
</cfif>



<hr />

<cfset myStructure = structNew()>
<cfset myStructure["Item1"] = "Hello there">

<cfdump var="#myStructure#" label="myStructure">

<cfif isDefined("myStructure['Item1']")>
    The variable myStructure.Item1 is defined <!--- It returns is defined --->
<cfelse>
    The variable myStructure.Item1 is not defined
</cfif>


I’m a little devastated that isdefined() is depracated. It seems such a simple and useful function.

What would be the sensible way of handling this…

<cfif isdefined("url.customer")>
  do some stuff here
</cfif>

Do you just replace the isdefined() with structkeyexists(url,“customer”) or is there a better way?

I’d be interested to know why it was depracated, if anyone knows.

Simon

StructKeyExists( url,“customer” ) is simply more efficient, especially under load

Imagine you are Lucee, and how you are going to execute that statement.

IsDefined

  1. does some string parsing
  2. figures out it’s an url variable
  3. then it’s going to do a structKeyExists on url to see if customer exists.

While structKeyExists only does step 3.

Just my 2 cents. One of the reasons I LOVE CFML is its natural language oriented and its very simple on the surface and allows you to plumb and extend the depths of it as programming skills develop.

To me:
isDefined is natural language orientated.
strucyKeyExists is not natural language oriented.

I like the natural language style tags, ColdFusion is littered with them, and it serves as a way for people who didn’t spend years honing their programming skills to create simple to complex applications.

2 Likes

@Simon_Goldschmidt that any sruff is marked as deprecated doesn’t mean you can’t use it. I still have some legacy code with tons of isdefined() in it and I won’t change it (for now()). Its more a business decision, because my fellow here (who is not a good programmer) needs to understand the steps and all the logic. He only knows legacy cfml stuff and no OOP.

Please read the following information to the definition “deprecated”
Deprecated Tags & Functions :: Lucee Documentation

@Terry_Whitney the reason you love cfml is the reason I’ve started with the language. I remember reading about cfloop in a Forta book, when I only knew loops with for/next commands from BASIC. There have been tons of such easy working tags. Love it!

3 Likes

ah good old basic, who doesn’t miss GOTO statements?

My first puter was CP/M box, with MBASIC, I had to figure out how to move the cursor around and clear the screen by poking at bits of memory so I could write some games

2 Likes

My very first computer was a TSR-color. My parents handed me a programming book and said here, you want video games, there they are. I was six at the time… 0 - CLS - 5 Beep (sound 1,10) 10 Go to 5 :slight_smile:

1 Like

Nice age to get an programming book. I remember the look&feel&smell of those books.

These computers have been out earlier than mine :smiley: : I began with a TK85 (16kb memory), it was a brazilian clone of the ZX81. Had to load the software from on old school tape recorder playing those compact cassettes. I was always crossing fingers to not see an error after the load. Once I got a programmer’s magazine which had a “space invaders” game code printed as a list of hex. You needed to write a small basic programm first in order to add the list bytes to the memory. Then
I played like forever, because as soon as you switched the power off, everything was gone.

1 Like

I remember those tape recorders… i did not have one until I was 8. My mother kept unplugging my computer and there was no storage, so in many cases, days of work would get destroyed.

Awesome thread!
There is stuff in here I didn’t know CF had!

In general terms - NOT CFML specific;
Can anyone give me a sample - (in general terms ./ pseudo-code) that will show the difference between the Elvis Operator and the Null coalescing operator?

EDIT:
Nevermind : I worked it out…
The NCO, checks that the variable exists and is NOT Null - and returns value of the variable/expression under test, if it exists and is not null, else the second expression

The EO, is a "shortened ternary operator…
Instead of
(expr1) ? (expr2) : (expr3),

Elvis gives us;
(expr1) ?: (expr3)

Thanks!
Gavin

@TonyMonast this is not a bug, that is expected behaviour. isDefined uses the same interpreter that is also used for evaluate. That means if a variable would fail because of an invalid syntax like
evaluate("susi.1=1") isDefined will also fail, in other words the synzax has to be valid. leading number for keys are only allowed when using [].
Take this example

sct[1]=123;
dump(isDefined("sct[1]")); // works 
dump(isDefined("sct['1']")); // works 
dump(isDefined("sct.1")); // fails

so simply wrap all your keys with [""] and you are good.

2 Likes

There is no difference in CFML. Elvis IS a null-coalescing operator. At least in Lucee. In Adobe, it’s an unholy combination of null-coaslescing and shortened ternary designed by-committee that makes it 100% worthless.

Not in CFML/Lucee, it’s not. Do not confuse other language like JS or Groovy’s implementation with CFML’s implementation. Javascript, for example is ONLY able to treat elvis as a shortened ternary because it has a loose definition of truthy and falsy values that allows any variable (including nulls) to be co-erced to a true/or false value. CFML deoes not have this loose truthy behavior and therefore can never work like JS or Groovy does

A shortened ternary requires that the first expression be truthy or falsy, meaning it can be cast to a boolean. CFML is only doing a null check. Elvis in CFML if the equivalent of

result = !isNull( expr1 ) ? expr2 : expr1
2 Likes

Hi @bdw429s,

My response was almost just for myself to try and understand the “general” concept of Elvis and NCO - not necessarily specific to any language.

Nonetheless, Thanks very much for the confirmation of how Elvis works with Lucee.
Gavin.

Different languages have implemented an “elvis” operator to work differently even though they may have the same name. So there is no global definition of what an “elvis” operator is. For example, Kotlin has an “elvis” operator, but it also works like Lucee CFML.

1 Like

I ran your timer script a couple dozen times on my laptop and it’s only 2-3 ms for each and isDefined() is actually the winner close to half of the results. Are there real world use cases verifying that a scoped isDefined() is significantly less efficient than StructKeyExists()?

Now, when the scope is removed e.g. isDefined("customer"), then that timer jumps to as high as 30ms.

But as long as it’s scoped, isn’t it practically just as good and definitely easier to read?

I think I just found the answer to my own question from a ColdFusion Muse article by Mark Kruger way back in 2009:

“isDefined() takes no notice of your dotted notation unless the first part of the string matches the scope it is examining at the time.”

So, I realize now that the insignificant performance difference on my laptop is probably because the timer script doesn’t have as much to traverse in all the scopes as there would be in most production servers.

2 Likes

good insight, thanks for sharing… always have to be careful with micro benchmarks

1 Like