Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy: println vs System.out.println with GroovyInterceptable

Tags:

groovy

Why do I need to use System.out.println instead of println when I use GroovyInterceptable?

For example if I am coding in a Groovy file I can just print to the console by typing:

println "Printing to Console"

But if I want to print here:

class Test implements GroovyInterceptable {
    def sum(Integer x, Integer y) { x + y }

    def invokeMethod(String name, args) {
        System.out.println "Invoke method $name with args: $args"
    }
}

def test = new Test()
test?.sum(2,3)

I have to use System.out.println in that method, or else I get a StackOverflowError. Why?

UPDATE: Thanks to @Dan Getz for the answer below I know why it happens with the GroovyInterceptable class now. Does anyone know if there are other class implementations in Groovy where this issue could arise?

like image 487
Celt Avatar asked Jun 04 '15 14:06

Celt


1 Answers

This is because your class Test implements the GroovyInterceptable interface, which according to the docs, is

used to notify that all methods should be intercepted through the invokeMethod mechanism of GroovyObject.

This isn't just methods that have been defined on your class. Try:

test?.total(2,3)

You'll see that it returns

Invoke method total with args: [2, 3]

The call to println inside invokeMethod is thus understood as a call to this.println, just like a call to sum would be. But this.println just calls invokeMethod again, because you implemented GroovyInterceptable, and so on.

This wouldn't happen if you didn't implement GroovyInterceptable. For example, running the following code

class Test {
    def sum(Integer x, Integer y) { 
        println "Let's sum!"
        x + y
    }
}

def test = new Test()
test?.sum(2,3)

Will output

Let's sum!

like image 53
Dan Getz Avatar answered Sep 17 '22 15:09

Dan Getz