"==" or "===" "!=" or "!=="

Hello,
Which are correct usages of “equal to” and “not equal to” in rules? Looking at examples posted on the forum, “==” and “===” seem to be interchangeable so do “!=” and “!==”. Any preference?
Thank you.

Generally you’ll use “==” and “!=” but the “===” and “!==” having something to do with null or NULL which are also different. At least for the most part you won’t do a lot of the === and !== thing.

Someone will come along and better explain it but if you’re stuck this will at least get you going.

The are definitely NOT interchangeable.

  • == : equals to, it compares the data of the two operands for equivalency
  • != : not equals, it compares the data of the two operands for non-equivalency
  • === : identity, it compares the two Objects to see if they are the same (i.e. both variable point to the same space in RAM)
  • !== : not identity, it compares the two Objects to see if they are not the same (i.e. both point to different space in RAM)

Here is an example.

var String foo = "foo"
var String foo2 = "foo"

foo == foo2 // true because both Objects are "foo"
foo != foo2 // false because both Objects are "foo"
foo === foo2 // false because foo and foo2 are two different Objects pointing to different places in memory
foo !== foo2 // true because both point to different places in memory
foo === foo // true because both point to the same place in memory

So why would one ever use ===/!==? As Scott pointed at but didn’t quite get right, we have null (not to be confused with NULL which is something different). When a variable is not initialized (i.e. it points to no place in memory) it is set to null.

null is a primitive meaning it doesn’t have any methods. When you use a ==/!= b, behind the scenes what is actually happening is a.equals(b). But null, being a primitive, means there is no .equals method to call on it. So the Rules parser will complain saying you must use ===/!== when one of the sides of the argument are explicitly null.

if(myValue === null)

This is the only time you should use ===/!==. In all other cases, including NULL you should use ==/!=.

11 Likes

Gonna bookmark this one this time around. you have no idea how hard it is to search for the difference on null and NULL :joy::joy::joy:

1 Like

Just for completeness then:

  • NULL - a state an Item can have indicating it has not been initialized
  • UNDEF - a state an Item can have indicating it’s state is undefined (e.g. there was an error reading the sensor value)

All Items can carried these two states. However, these states cannot be cast to other types. So, for example, if you have a Number Item whose state is NULL and you try:

MyNumberItem.state as Number

You will get an exception in the logs, probably a null exception, because a NULL is not of type Number. So it is always a good idea to check for and deal with NULL and UNDEF states in your Rules.

2 Likes

Thank you.

Before I started using mapdb to restore all states at startup ( /hat tip to you ) I would run into this and my way of dealing with it was checking for any state other than the one I wanted which worked well for catching NULLS, but as I said I don’t run into it much any more.

I’m glad that I asked the question. There is no way I can figure this one out myself. null and NULL discussion is a bonus. Thank you Scott and Rick.

1 Like