0

I'm learning groovy to work on smartthings and found a relatively common command among the various examples and existing code (see below).

Reading the function of the && operator I would think the "&& cmd.previousMeterValue" is superfluous. Or is there some code shortcut I'm missing?

Thanks John

if (cmd.previousMeterValue && cmd.previousMeterValue != cmd.meterValue) {
do something
}
JonRob
  • 43
  • 1
  • 6
  • You misread, the precedence is not as you think. This is evaluated as `cmd.previousMeterValue && (cmd.previousMeterValue != cmd.meterValue)` (basically, true if previous value exists, and is different than the current one) – Amadan Jun 18 '18 at 00:43
  • Thank you for the clarification. I however I'm not sure why the statement is not simply cmd.prevousvalue != cmd.currentvalue. However it might be some unique SmartThings requirement. I'll ask there. Again thanks, your answer was helpful. – JonRob Jun 18 '18 at 01:48

1 Answers1

2

Not knowing what type previousMeterValue has, this answer is somewhat generic.

Groovy follows common operator precedence, i.e. != is evaluated before &&.
To show it explicitly, the full expression is the same as:

(cmd.previousMeterValue) && (cmd.previousMeterValue != cmd.meterValue)

cmd.previousMeterValue is testing the value for the Groovy-Truth.
Depending on value type, the following might be applicable:

  • Non-null object references are coerced to true.
  • Non-zero numbers are true.

So if the value is null or 0, the expression is false.

If the first part of the expression evaluated to false, then the second part is skipped.

The logical && operator: if the left operand is false, it knows that the result will be false in any case, so it won’t evaluate the right operand. The right operand will be evaluated only if the left operand is true.

If the first part of the expression evaluated to true, then cmd.previousMeterValue != cmd.meterValue is evaluated, using the following rule:

In Groovy == translates to a.compareTo(b)==0, if they are Comparable, and a.equals(b) otherwise.

So if value is a number object, then it is evaluated as:

cmd.previousMeterValue.compareTo(cmd.meterValue) != 0

This means that BigDecimal values are compared by value, ignoring specific scale.

Andreas
  • 154,647
  • 11
  • 152
  • 247