Search

Dark theme | Light theme
Showing posts with label GroovyGoodness:Operators. Show all posts
Showing posts with label GroovyGoodness:Operators. Show all posts

March 8, 2020

Groovy Goodness: Check Object Instances Are The Same With === Operator

Groovy has used the == operator to check if objects are equal for a long time. To test if object instances are the same we must use the is method. Groovy 3 adds a new operator for the is method and that is the === operator. And to negate the result of the is method we can use the !== operator.

In the following example we use the === and !== operator to check if objects refer to the same instance or not:

def answer = new Integer(42)
def anotherAnswer = new Integer(42)
def meaningOfLife = answer

// Equals is true for answer and anotherAnswer
assert answer == anotherAnswer

// But they don't refer to the same instance.
assert answer !== anotherAnswer

// The variables meaningOfLife and answer
// do refer to the same object instance.
assert answer === meaningOfLife

Written with Groovy 3.0.2.

March 4, 2020

Groovy Goodness: Using !instanceof Operator

Groovy 3 adds the !instanceof operator to check if an object is not an instance of a type. This is a shorthand for using instanceof and then negate the result. It shows how little changes can make code easier to read.

In the following example we use the old way to check if object is not an instance of a type and the new !instanceof operator:

// Check using !(obj instanceof type) 
// if object is not an instance of type.
assert !("Groovy is awesome!" instanceof Number)

// Since Groovy 3 we can use !instanceof to check
// if object is not an instance of a type.
assert 42 !instanceof String

Written with Groovy 3.0.1.

February 27, 2020

Groovy Goodness: The Elvis Assignment Operator

Groovy 3 adds a new operator to the language: elvis assignment operator (?=). This operator is a shorthand for an assignment where we want to assign a value to a variable or property if the variable or property is null or false (following Groovy truth). If the value of the variable or property is not null or false (again apply Groovy truth rules), the value stays the same.

In the following example code we use the elvis assignment operator:

// First an example using the elvis operator.
a = null
a = a ?: 100

assert a == 100

// Now we can shorten the assignment using the 
// elvis assignment operator.
a = null
a ?= 100

assert a == 100

b = 200
b ?= 100

assert b == 200

// The elvis assignment operator can also 
// be useful in maps to set default values.
def m = [a: 1, b: 2]
m.a = 100
m.b ?= 200
m.c ?= 300

assert m.a == 100
assert m.b == 2
assert m.c == 300

// Also to set default values for properties
// in an object. Especially if we cannot
// change the class to set a default value.
// In our example we have the source of the
// Email class and we could set default values
// in the class definition, but if the class
// is not under our control we can use the
// elvis assignment operator to set default
// values easily.
class Email {
    String to, from, subject, body
}

def mail = new Email(to: 'test@mrhaki.com', 
                     subject: 'Sample', 
                     body: 'Trying Elvis assignment.')
mail.subject ?= 'Mail has no subject'
mail.from ?= 'no-reply@mrhaki.com'

assert mail.to == 'test@mrhaki.com'
assert mail.from == 'no-reply@mrhaki.com'
assert mail.subject == 'Sample'
assert mail.body == 'Trying Elvis assignment.'

Written with Groovy 3.0.1.

February 18, 2017

Groovy Goodness: Using The Call Operator ()

In Groovy we can add a method named call to a class and then invoke the method without using the name call. We would simply just type the parentheses and optional arguments on an object instance. Groovy calls this the call operator: (). This can be especially useful in for example a DSL written with Groovy. We can add multiple call methods to our class each with different arguments. The correct method is invoked at runtime based on the arguments.

In the following example we have User class with three call method implementations. Next we see how we invoke the call methods, but without typing the method name and just use the parenthesis and arguments:

import groovy.transform.ToString
@ToString(includeNames = true)
class User {
    
    String name
    String alias
    String email
    String website
    
    // Set name.
    def call(final String name) {
        this.name = name
        this
    }
    
    // Use properties from data to assign
    // values to properties.
    def call(final Map data) {
        this.name = data.name ?: name
        this.alias = data.alias ?: alias
        this.email = data.email ?: email
        this.website = data.website ?: website
        this
    }
    
    // Run closure with this object as argument.
    def call(final Closure runCode) {
        runCode(this)
    }
    
}


def mrhaki = 
    new User(
        name: 'Hubert Klein Ikkink',
        alias: 'mrhaki',
        email: 'mrhaki@email.nl',
        website: 'https://www.mrhaki.com')
        
// Invoke the call operator with a String.
// We don't have to explicitly use the
// call method, but can leave out the method name.
// The following statement is the same:
// mrhaki.call('Hubert A. Klein Ikkink')
mrhaki('Hubert A. Klein Ikkink')

// Of course parentheses are optional in Groovy.
// This time we invoke the call method
// that takes a Map arguemnt.
mrhaki email: 'h.kleinikkink@email.nl'

assert mrhaki.name == 'Hubert A. Klein Ikkink'
assert mrhaki.alias == 'mrhaki'
assert mrhaki.email == 'h.kleinikkink@email.nl'
assert mrhaki.website == 'https://www.mrhaki.com'


// We can pass a Closure to the call method where
// the current instance is an argument for the closure.
// By using the call operator we have a very dense syntax.
mrhaki { println it.alias }  // Output: mrhaki

// Example to transform the user properties to JSON.
def json =  mrhaki { 
    new groovy.json.JsonBuilder([vcard: [name: it.name, contact: it.email, online: it.website]]).toString()
} 

assert json == '{"vcard":{"name":"Hubert A. Klein Ikkink","contact":"h.kleinikkink@email.nl","online":"https://www.mrhaki.com"}}'

Written with Groovy 2.4.8.

January 16, 2010

Groovy Goodness: Apply Method to All Elements in a List

In Groovy we have several ways to achieve the same thing. For example we can apply a method to all elements in a list with the collect() method or with *..

class User { 
    String name 
    String aloud() { name.toUpperCase() }
    String toString() { name }
}

def users = [new User(name: 'mrhaki'), new User(name: 'hubert')]

assert ['mrhaki', 'hubert'] == users*.toString()
assert ['MRHAKI', 'HUBERT'] == users*.aloud()
assert ['mrhaki', 'hubert'] == users.collect { it.toString() }
assert ['MRHAKI', 'HUBERT'] == users.collect { it.aloud() }

January 15, 2010

Groovy Goodness: Is Object in Class Hierarchy

With Groovy's in keyword we can check if an object is assignable for a class in the class hierarchy (noted by Andrey Paramonov - see comment section). This way we can check if the object is an instance of a certain class or one of the parents of the class or to be more specific, if the class is assignable for the class or parent classes. This can also be useful when checking if an exception for example is part of an exception hierarchy.

class Shape { }
class Circle extends Shape { }
class Square extends Shape {}

// Create Square instance.
def square = new Square()

assert square in Shape
assert square in Square
assert !(square in Circle)

[Shape.class, Square.class].each {
    assert square in it
}

November 21, 2009

Groovy Goodness: Are You In? (Membership Operator)

Groovy brings some new operators and keywords to the table. One of them is the in keyword or the so-called membership operator. The operator can be called in a conditional context, for example we can use in to test for the existince of a member in a collection. We can write our own implementation by implementing the isCase() method of our class. Or the operator is called in an iterative context, for example in a for loop. Then the iterator() is called. We can write our own implementation for the iterator() to implement in when called in a iterative context.

// *** Conditional context
def list = ['Groovy', 'Java']
assert 'Groovy' in list
assert !('Scala' in list)

// Write our own in implementation.
class MyObject {
    String value
    boolean isCase(ch) { 
        value.contains(ch) 
    }
}
def myObj = new MyObject(value: 'Groovy')
assert 'oo' in myObj
assert !('oo' in myObj.value)  // isCase for String invokes equals.
assert 'Groovy' in myObj
assert 'Groovy' in myObj.value
assert !('a' in myObj)

// *** Iterative context
// Use in in a for loop.
def result = ''
for (lang in list ) {
    result += lang
}
assert 'GroovyJava' == result

class Counter {
    Integer maxValue
    private Integer counter = 0
    Iterator iterator() {
        [hasNext: { counter <= maxValue }, 
         next: { counter++ }] as Iterator
    }
}
def counter = new Counter(maxValue: 10)
result = '' 
for (c in counter) {
    result += c
}
assert result == '012345678910'

September 3, 2009

Groovy Goodness: the Spread Operator

In a previous post we learned about the spread-dot operator, in this post we look at the spread operator. The spread operator (*) is used to tear a list apart into single elements. This can be used to invoke a method with multiple parameters and then spread a list into the values for the parameters. The spread operator can also be used to add lists or ranges to lists and to add maps to other maps.

class Simple {
    String speak(Integer n, String text, Date date) {
        def out = new StringBuffer()
        n.times { 
            out << "Say $text on ${date.format('yyyy-MM-dd')}.\n" 
        }
        out
    }
}

// Spread params list for speak() method.
def params = [
    2,
    "hello world",
    new Date().parse("yyyy/MM/dd", "2009/09/01")
]
assert '''Say hello world on 2009-09-01.
Say hello world on 2009-09-01.
''' == new Simple().speak(*params)

// Add a list to another list.
def list = ['Groovy', 'Java']
assert ['Groovy', 'Java', 'Scala'] == [*list, 'Scala']

// Add a range to a list.
def range = 2..5
assert [1, 2, 3, 4, 5, 6] == [1, *range, 6]

// Add a map to another map.
def map = [name: 'mrhaki', blog: true]
assert [name: 'mrhaki', blog: true, subject: 'Groovy Goodness'] == [subject: 'Groovy Goodness', *:map]

// Little trick to simulate named parameters for a method.
// It is just a trick so the ordering of the map key/values
// must be the same as the method parameters.
def paramsMap = [
    n: 1, 
    text: 'hello', 
    date: new Date().parse("yyyy/MM/dd", "2009/09/04")
]
def paramsList = paramsMap.values().toList()
assert 'Say hello on 2009-09-04.\n' == new Simple().speak(*paramsList)

August 30, 2009

Groovy Goodness: The Spread-Dot Operator

Groovy adds some nice operators to the language to write brief code. We already learned about the Elvis operator and the Spaceship operator. And now we see what the spread-dot operator is about and what it does.

The spread-dot operator (*.) is used to invoke a method on all members of a Collection object. The result of using the spread-dot operator is another Collection object. Here is some sample code:

class Language {
    String lang
    def speak() { "$lang speaks." }
}

// Create a list with 3 objects. Each object has a lang 
// property and a speak() method. 
def list = [     
    new Language(lang: 'Groovy'),     
    new Language(lang: 'Java'),     
    new Language(lang: 'Scala') 
]  

// Use the spread-dot operator to invoke the speak() method. 
assert ['Groovy speaks.', 'Java speaks.', 'Scala speaks.'] == list*.speak() 
assert ['Groovy speaks.', 'Java speaks.', 'Scala speaks.'] == list.collect{ it.speak() }  

// We can also use the spread-dot operator to access 
// properties, but we don't need to, because Groovy allows 
// direct property access on list members. 
assert ['Groovy', 'Java', 'Scala'] == list*.lang 
assert ['Groovy', 'Java', 'Scala'] == list.lang

August 26, 2009

Groovy Goodness: the Spaceship Operator

Groovy adds some nice operators to the language. One of them is the spaceship operator. It's called the spaceship operator, because we use the following syntax <=> and that looks a bit like a UFO. The operator is another way of referring to the compareTo method of the Comparable interface. This means we can implement the compareTo method in our own classes and this will allow us to use the <=> operator in our code. And of course all classes which already have implemented the compareTo method can be used with the spaceship operator. The operator makes for good readable sort methods.

class Person implements Comparable {
    String username
    String email

    int compareTo(other) {
        this.username <=> other.username
    }
}

assert -1 == ('a' <=> 'b')
assert 0 == (42 <=> 42)
assert -1 == (new Person([username:'mrhaki', email: 'test@email.com']) <=> new Person([username:'zavaria', email:'tester@email.com']))
assert [1, 2, 3, 4] == [4, 2, 1, 3].sort{ a, b -> a <=> b }

Run this script in GroovyConsole.

August 19, 2009

Groovy Goodness: Turn Methods into Closures

Groovy supports closures and they are very useful when we create Groovy applications. For example we can pass closures as arguments to methods to execute them. We can create closures ourselves, but we can also convert a method to a closure with the .& operator. And we can use the converted method just like a normal closure. Because Groovy can use Java objects we can also convert a Java method into a closure.

Let's start with a simple Java class:

public class JavaObject {
 public static void javaSays(final String s) {
  System.out.println("Java says: Hello " + s + "!");
 }
}

With the following script we use this Java class and convert the javaSays method to a closure:

// Simple list with names.
def names = ['groovy', 'grails', 'mrhaki']

// Simple closure.
names.each { println 'Normal closure says: Hello ' + it + '!' }

// Groovy method to convert to closure.
def groovySays(s) {
 "Groovy says: Hello ${s}!"
}
// Use .& syntax to convert method to closure.
names.each(this.&groovySays)

// Convert Java method to closure and use it.
def javaSays = JavaObject.&javaSays
names.each javaSays

If we run this script we get the following output:

Normal closure says: Hello groovy!
Normal closure says: Hello grails!
Normal closure says: Hello mrhaki!
Groovy says: Hello groovy!
Groovy says: Hello grails!
Groovy says: Hello mrhaki!
Java says: Hello groovy!
Java says: Hello grails!
Java says: Hello mrhaki!

August 17, 2009

Groovy Goodness: Safe Navigation to Avoid NullPointerException

Little things in live can be such a joy. The safe navigation operator in Groovy is such a little thing. Suppose we have modelled a simple domain like this:

class Company {
    Address address
    String name
}

class Address {
    Street street
    String postalCode
    String city
}

class Street { 
    String name
    String number
    String additionalInfo
}

We want to display the streetname, but we don't know if all object instances are available. To avoid a NullPointerException we write the following code:

// company can be null.
if (company != null && company.getAddress() != null && company.getAddress().getStreet() != null) {
    println company.address.street.name
}

Groovy adds the safe navigation operator to shorten all this to:

// company can be null.
println company?.address?.street?.name

If one of the objects was null, the output of the total statement is null. We will not get any NullPointerExceptions.

Groovy Goodness: the Elvis Operator ?:

Groovy is good at shortening normal Java statements. The Elvis operator is to shorten the ternary operator. If we have a sensible default when the value is null or false (following Groovy truth rules) we can use the Elvis operator. And why is it called the Elvis operator? Turn your head to the left and you will know.

def sampleText

// Normal ternary operator.
def ternaryOutput = (sampleText != null) ? sampleText : 'Hello Groovy!'

// The Elvis operator in action. We must read: 'If sampleText is not null assign
// sampleText to elvisOuput, otherwise assign 'Viva Las Vegas!' to elvisOutput.
def elvisOutput = sampleText ?: 'Viva Las Vegas!'