Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

The Groovy Language


[ 74 ]

The Elvis operator has the added benefit of avoiding a second evaluation of the
initial predicate. This may be important if x is either expensive to evaluate, has
unwanted side effects, or results in an operation that we don't necessarily want to
repeat (such as a database retrieval). The Elvis operator works by maintaining a
hidden local variable, which stores the initial result. If that result is true according
to the rules of Groovy Truth, then that value is returned, otherwise, the alternative
value is used.


Suppose that we want to retrieve shopping cart items in a Map so that we can display
a list of selected items. If the check database and the cart contain entries, then that
is the Map that we want to display. If there are no items in the cart, then we want to
return a Map, which contains a dummy entry to display that just says that the cart is
empty. If we use regular conditional logic, we can't use a ternary operator because
we don't really want to check the cart twice. We would have to write something like
the following to manage a temporary map while we decide what to do with it:


cartItemsMap = Cart.getItems()

if ( cartItemsMap ) // Groovy true if map has entries in it
return cartItemsMap
else
return ["-1": "empty"]

Cart.getItems returns a Map, which in Groovy Truth is true if it has elements
and false if it is empty. Knowing this, we can rewrite the same code as a succinct
one-liner:


return Cart.getItems() ?: ["-1": "empty"]

Spaceship and Elvis operators

We can't look at the Elvis operator without also looking at the other oddly name
"spaceship" operator. The spaceship operator is comprised of two angle brackets
and an equals sign <=> and is so named because it resembles a UFO or spaceship in
flight. Spaceship is a shorthand operator that works the same as Java's compareTo
method. In other words, it compares two operands and returns 0 if they are equal, -1
if the first is less than the second, and 1 if the first is greater than the second. We can
express how the spaceship operator works with a simple block of Spock code.
Try this out yourself and play with different values for b and c:


expect:
a == (b <=> c)
and:
(b <=> c) == b.compareTo(c)

http://www.ebook3000.com
Free download pdf