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.,

[java]
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.
[/java]

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:
[java]Eval.x(java.lang.Object x, java.lang.String expression)[/java]

Its usage is like this:

[java]assert 10 == Eval.x(2, ‘ x * 4 + 2’)[/java]

and I wrote:

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

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

[java]

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’)
[/java]

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 Reply

Your email address will not be published. Required fields are marked *