Evaluating Expressions with groovy.util.Eval

27 / Aug / 2012 by Imran Mir 3 comments

A few days ago I faced a problem of evaluating dynamic expressions on domain objects. The scenario was that, depending upon the user input, I needed to sort a list of objects on some properties, which were nested deep in the object, e.g.,

student.course?.college?.name  // if a user chose to sort students by college name
student.course.teacher.name // if a user chose to sort students by teacher name.

Using if, else could not have been an elegant solution, considering that there were many more fields to be sorted upon. This is when groovy.util.Eval class came to my notice. I found a useful function there:

Eval.x(java.lang.Object x, java.lang.String expression)

Its usage is like this:

assert 10 == Eval.x(2, ' x * 4 + 2')

and I wrote:

students.sort {Eval.x(it, "x.${sortField}")} // sortField could be student.course?.college?.name

In addition to this, groovy.util.Eval has some more useful methods like:


assert 10 == Eval.me(' 2 * 4 + 2')
assert 10 == Eval.xyz(2, 4, 2, ' x * y + z')
assert 10 == Eval.xy(2, 4, ' x * y + 2')

Hope this helps.
Imran Mir
imran[@]intelligrape.com

FOUND THIS USEFUL? SHARE IT

comments (3)

  1. Igor Sinev

    Hi!

    Am I missing something or just
    students.sort { it.”${sortField}” }
    would do the trick?

    This example worked for me:

    def list = [new B(x: 1, y: 20), new B(x: 10, y: 1)]
    for (s in [‘x’, ‘y’]) {
    println list.sort { it.”${s}” }
    }

    @groovy.transform.Canonical
    class B {
    int x
    int y
    }

    Cheers,
    Igor Sinev

    Reply
  2. Farid

    Thanks for sharing Imran

    I used it once for using a string as a Map.

    def myMap = Eval.me(“[key1:val1,key2:val2]”)
    assert myMap.key1 == ‘val1′
    assert myMap.key2 == ‘val2′

    Reply

Leave a comment -