Search

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

March 10, 2016

Groovy Goodness: Using Tuples

A tuple is an ordered, immutable list of elements. Groovy has it's own groovy.lang.Tuple class. We can create an instance of a Tuple by providing all elements that need to be in the Tuple via the constructor. We cannot add new elements to a Tuple instance or remove elements. We cannot even change elements in a tuple, so it is completely immutable. This makes it very useable as return value for a method where we need to return multiple values. Groovy also provides a Tuple2 class that can be used for tuple instance of only two elements. The elements are typed in a Tuple2 instance.

In the following example we see different uses of the Tuple and Tuple2 classes:

def tuple = new Tuple('one', 1, new Expando(number: 1))

assert tuple.size() == 3

// To get the value of an element
// at a certain position we use
// the get(index) method.
assert tuple.get(0) == 'one'

// We can use the [] syntax to
// get elements from the tuple.
assert tuple[1] == 1

// We can use methods added to the
// Collection API by Groovy.
assert tuple.last().number == 1

// We cannot change the tuple.
try {
    tuple.add('extra')
    assert false
} catch (UnsupportedOperationException e) {
    assert e
}

try {
    tuple.remove('one')
    assert false
} catch (UnsupportedOperationException e) {
    assert e
}

try {
    tuple[0] = 'new value'
    assert false
} catch (UnsupportedOperationException e) {
    assert e
}


// Create a Tuple with fixed size 
// of 2 elements, a pair.
def pair = new Tuple2('two', 2)

// The Tuple2 class has extra methods
// getFirst() and getSecond() to 
// access the values.
assert pair.first == 'two'
assert pair.second == 2

An example on how to use a Tuple2 as return value for a method:

def calculate(String key, Integer... values) {
    // Method return a Tuple2 instance.
    new Tuple2(key, values.sum())
}

// Use multiple assignment to
// extract the values from the tuple.
// Tuple2 has typed objects.
def (String a, Integer b) = calculate('sum', 1, 2, 3)

assert a == 'sum'
assert b == 6

Written with Groovy 2.4.6.

November 22, 2009

Groovy Goodness: Finding Files with FileNameFinder

The groovy.util package contains the FileNameFinder and FileNameByRegExFinder classes. We can use the FileNameFinder classe to search recursively for files in a directory with ANT fileset pattern conventions. With the FileNameByRegExFinder we use regular expressions to define the file patterns.

// Suppose we have a environment variable GROOVY_HOME pointing to the Groovy installation dir.
def groovyHome = System.getenv('GROOVY_HOME')

def txtFiles = new FileNameFinder().getFileNames(groovyHome, '**/*.txt' /* includes */, '**/*.doc **/*.pdf' /* excludes */)
assert new File(groovyHome, 'README.txt').absolutePath in txtFiles

def icoFiles = new FileNameByRegexFinder().getFileNames(groovyHome, /.*\.ico/)
assert new File(groovyHome, 'html/groovy-jdk/groovy.ico').absolutePath in icoFiles

September 13, 2009

Groovy Goodness: Exception Handling

Handling exceptions in Groovy is the same as in Java. We write a try-catch block to catch an exception and handle it. But there is a twist: in Groovy every exception is optional. This goes for checked exceptions as well. Groovy will pass an exception to the calling code until it is handled, but we don't have to define it in our method signature. So we as developers can choose how and when to handle the exception.

We all have seen code where developers have to handle checked exceptions, because otherwise the Java source code will not compile. And what ends up in the catch block? Mostly what the IDE generates, or ex.printStackTrace(), or any other code that handles the exception without any thought. In Groovy we can choose at which level we want to catch an exception. If we don't do anything the exception will be passed on to the calling code. So without a compiler grinding to a halt with errors about exception handling we must have a good discipline to do this ourselves in Groovy.

try {
    def url = new URL('malformedUrl')
    assert false, 'We should never get here because of the exception.'
} catch (MalformedURLException e) {
    assert true
    assert e in MalformedURLException
}

// Method throws MalformedURLException, but we don't 
// have to define it. Groovy will pass the exception
// on to the calling code.
def createUrl() {
    new URL('malformedUrl')
}

try {
    def url1 = createUrl()
    assert false, 'We should never get here because of the exception.'
} catch (all) {  // Groovy shortcut: we can omit the Exception class 
                 // if we want to catch all Exception and descendant objects. 
                 // In Java we have to write catch (Exception all).
    assert true
    assert all in MalformedURLException
}

Run this script in GroovyConsole.