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
}
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.
Related
I am building DSL and try to define a custom class CustomClass that you can use in expressions like
def result = customInstance >= 100 ? 'a' : 'b'
if (customInstance == 'hello') {...}
Groovy doesn't call == when your class defines equals and implements Comparable (defines compareTo) at the same time.
Instead Groovy calls compareToWithEqualityCheck which has a branching logic. And unless your custom DSL class is assignable from String or Number your custom compareTo won't be called for the example above.
You can't extend CustomClass with String.
I feel like I am missing something. Hope you can help me figure out how to implement a simple case like I showed above.
Here is a short answer first: You could extend GString for the CustomClass. Then its compareTo method will be called in both cases - when you check for equality and when you actually compare.
Edit: Considering the following cases, it will work for 1 and 2, but not for 3.
customInstance >= 100 // case 1
customInstance == 'hallo' // case 2
customInstance == 10 // case 3
Now I will explain what I understand from the implementation in Groovy's ScriptBytecodeAdapter and DefaultTypeTransformation.
For the == operator, in case Comparable is implemented (and there is no simple identity), it tries to use the interface method compareTo, hence the same logic that is used for other comparison operators. Only if Comparable is not implemented it tries to determine equality based on some smart type adjustments and as an ultima ratio falls back to calling the equals method. This happens in DefaultTypeTransformation.compareEqual#L603-L608
For all other comparison operators such as >=, Groovy delegates to the compareToWithEqualityCheck method. Now this method is called with the equalityCheckOnly flag set to false, while it is set to true for the first case when it the invocation originates from the == operator. Again there is some Groovy smartness happening based on the type of the left side if it is Number, Character, or String. If none applies it ends up calling the compareTo method in DefaultTypeTransformation.compareToWithEqualityCheck#L584-L586.
Now, this happens only if
!equalityCheckOnly || left.getClass().isAssignableFrom(right.getClass())
|| (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass())) //GROOVY-4046
|| (left instanceof GString && right instanceof String)
There are some restrictions for the case of equalityCheckOnly, hence when we come from the == operator. While I can not explain all of those I believe these are to prevent exceptions to be thrown under specific circumstances, such as the issue mentioned in the comment.
For brevity I omitted above that there are also cases that are handled upfront in the ScriptBytecodeAdapter and delegated to equals right away, if left and right hand side are both of the same type and one of Integer, Double or Long.
I'm trying to take a number of input strings and have a
do {
} while
loop matching the strings with
while (!sqlw.equals(w) && !sqlc.equals(c));
However this returns positive match if either one or the other is matched, rather than both. Any ideas? I guess it is something simple.
So, the thing is, in this line:
while (!sqlw.equals(w) && !sqlc.equals(c));
the expression becomes false if either sqlw.equals(w) is true (making !sqlw.equals(w) false) or !sqlc.equals(c) is true (making !sqlc.equals(c) false).
Try replacing && with || like so
while (!sqlw.equals(w) || !sqlc.equals(c));
That way, the expression is false only if !sqlw.equals(w) and !sqlc.equals(c) are both false (i.e. when both match).
EDIT: You could also change it to
while (!(sqlw.equals(w) && sqlc.equals(c)));
which does the same thing but is perhaps a little more faithful to what you wanted (loop while we haven't matched both).
The equals method returns a boolean value. Try sqlw.equals('w') == false.
Also make sure your data types are the same in both cases. One might be a string and the other an array object of some sort.
According to the Groovy docs, the == is just a "clever" equals() as it also takes care of avoiding NullPointerException:
Java’s == is actually Groovy’s is() method, and Groovy’s == is a clever equals()!
[...]
But to do the usual equals() comparison, you should prefer Groovy’s ==, as it also takes care of avoiding NullPointerException, independently of whether the left or right is null or not.
So, the == and equals() should return the same value if the objects are not null. However, I'm getting unexpected results on executing the following script:
println "${'test'}" == 'test'
println "${'test'}".equals('test')
The output that I'm getting is:
true
false
Is this a known bug related to GStringImpl or something that I'm missing?
Nice question, the surprising thing about the code above is that
println "${'test'}".equals('test')
returns false. The other line of code returns the expected result, so let's forget about that.
Summary
"${'test'}".equals('test')
The object that equals is called on is of type GStringImpl whereas 'test' is of type String, so they are not considered equal.
But Why?
Obviously the GStringImpl implementation of equals could have been written such that when it is passed a String that contain the same characters as this, it returns true. Prima facie, this seems like a reasonable thing to do.
I'm guessing that the reason it wasn't written this way is because it would violate the equals contract, which states that:
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
The implementation of String.equals(Object other) will always return false when passed a GSStringImpl, so if GStringImpl.equals(Object other) returns true when passed any String, it would be in violation of the symmetric requirement.
In groovy a == b checks first for a compareTo method and uses a.compareTo(b) == 0 if a compareTo method exists. Otherwise it will use equals.
Since Strings and GStrings implement Comparable there is a compareTo method available.
The following prints true, as expected:
println "${'test'}".compareTo('test') == 0
The behaviour of == is documented in the Groovy Language Documentation:
In Java == means equality of primitive types or identity for objects. In Groovy == means equality in all cases. It translates to a.compareTo(b) == 0, when evaluating equality for Comparable objects, and a.equals(b) otherwise. To check for identity (reference equality), use the is method: a.is(b). From Groovy 3, you can also use the === operator (or negated version): a === b (or c !== d).
The full list of operators are provided in the Groovy Language Documentation for operator overloading:
Operator
Method
+
a.plus(b)
-
a.minus(b)
*
a.multiply(b)
/
a.div(b)
%
a.mod(b)
**
a.power(b)
|
a.or(b)
&
a.and(b)
^
a.xor(b)
as
a.asType(b)
a()
a.call()
a[b]
a.getAt(b)
a[b] = c
a.putAt(b, c)
a in b
b.isCase(a)
<<
a.leftShift(b)
>>
a.rightShift(b)
>>>
a.rightShiftUnsigned(b)
++
a.next()
--
a.previous()
+a
a.positive()
-a
a.negative()
~a
a.bitwiseNegate()
Leaving this here as an additional answer, so it can be found easily for Groovy beginners.
I am explicitly transforming the GString to a normal String before comparing it.
println "${'test'}".equals("test");
println "${'test'}".toString().equals("test");
results in
false
true
I know && is the logical operator here, also conditions on the left and on the right are operands, right?
Like:
1+1 is an expression where + is the operator and the numbers are operands. I just do not know whether the condition itself is called the operand as well because it get compared by an operator. I guess so.+
Thanks
What are the parts called?
>, &&, and == are all operators. Operands are the values passed to the operators. x, y, and z are the initial operands. Once x > y and z == 5 are evaluated, those boolean results are used as the operands to the && operator which means the expressions themselves are not the operands to &&, the results of evaluation those expressions are the operands.
When you put operands and an operator together, you get an expression (i.e. x > y, z == 5, boolResult == boolResult)
How are they evaluated?
In most (if not all) languages x > y will be evaluated first.
In languages that support short circuiting, evaluation will stop if x > y is false. Otherwise, z == 5 is next.
Again, in languages that support short circuiting, evaluation will stop if z == 5 is false. Otherwise, the && will come last.
>, &&, and == are all operators. Operands are the values passed to the operators. x, y, and z are the initial operands. Once x > y and z == 5 are evaluated, those boolean results are used as the operands to the && operator.
One alternative would be to turn to the grammar of C#
It states the following:
conditional-and-expression && inclusive-or-expression
Just generalizing it as "expressions" is probably accurate enough :)
If your question is really what the parts left and right of the && are called, I’d say “expression”, maybe “boolean expression”.
Conditions, or in case of ||: Alternatives
In c# the && is an operator and the left and right are expressions. In an if statement, if the left evaluates to true the right will never be evaluated.
It's a boolean comparison expression that's comprised of two separate boolean comparison expressions.
Depending on the language, how this is interpreted depends on operator precedence. Since it looks like a C-like dialect, I'll assume && is short-circuit AND. (More explanation here).
Order of operations would be left to right as the equality testers (>, >=, <=, ==, !=) have equal precedence to boolean operations (&&, ||).
x > y would be evaulated, and if true, z == 5 would be evaluated, and then the first and second results would be ANDed together. However, if x > y was false, the expression would immediately return false, due to short-circuiting.
You're correct that x>y and z==5 are operands, and && is an operator. In addition, both of these operands in turn contain their own operands and operators. These are called complex operands
So:
x>y and z==5 are operands to the operator &&
x and y are operands to the operator >
z and 5 are operands to the operator ==
Regarding the individual component parts and how to name them:
Both == and > are comparison operators, which compare the values of two operands.
== is an equality operator, and evaluates to true if the left operand is equal to the right operand.
> is a greater than operator, and evaluates to true if the left operand is greater than the right operand.
&& is a logical operator, specifically logical AND. It evaluates to true if both the left and the right operand are true.
When referring to each operand, it's standard to refer to them by their position, i.e. the left operand and right operand - although there's no "official" name - first and second operand work equally well. Note that some operators such as ! have only one operand, and some even have 3 (the ternary operator, which takes the form condition ? true_value : false_value
Is this well defined?
Streamreader ^reader = gcnew Streamreader("test.txt");
String ^line;
while ((line = reader->ReadLine()) != nullptr && line != "")
{
//do stuff
}
I believe that I read somewhere that it is not guaranteed that the assignment is executed before the 2nd conditional. It may be that I'm wrong or that this just applies for C.
Google did not help me with this, that is why I am asking here :)
With && and ||, it is guaranteed to evaluate the first condition (including the assignment) before evaluating the second condition.
With bitwise & and |, on the other hand, no such guarantees are made.
There is a related answer here with a number of good references: Is short-circuiting logical operators mandated? And evaluation order?
Short answer if you haven't overloaded && and || you'll get short-circuit evaluation, which goes from left to right. Take a look in the link.