How to get something like anonymous inner class in Groovy?

How to define an anonymous inner class in Groovy? I saw links that should have been supported in Groovy 1.7, and I'm using 1.8.

thread = process.consumeProcessOutput( new Appendable() { Appendable append(char c) { app1.append(c) app2.append(c) return this } Appendable append(CharSequence csq) { app1.append(csq) app2.append(csq) return this } Appendable append(CharSequence csq, int start, int end) { app1.append(csq, start, end) app2.append(csq, start, end) return this } }) 

I get an exception with this code:

 Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.UNIXProcess.consumeProcessOutput() is applicable for argument types: (MyClass$1) values: [ MyClass$1@19c8ef56 ] 
+7
source share
4 answers

This is a difficult case, since methods must return the object itself as Appendable and has an overloaded method name that does not work well with the groovy map for casting the interface. The easiest and most understandable way is probably just to use an anonymous inner class, as in Java. This requires a reasonably current groovy version (1.7 or newer, I think):

 def testAppendable(Appendable appendable) { println "appendable = $appendable" appendable.append('a' as char). append('b' as char). append('c' as char) } testAppendable(new Appendable() { Appendable append(char c) { println "got $c" this } Appendable append(CharSequence csq) { this } Appendable append(CharSequence csq, int start, int end) { this } String toString() { "inner class appendable" } }); 

Another alternative would be to use Expando with closure. This is a bit inconvenient, since in the constructor you can initialize only one implementation per method name. Note that any skipped interface methods are set by default, which cause an exception.

 testAppendable(new Expando( append: { char c -> println "got $c" delegate as Appendable }, toString: { -> "expando appendable" } ) as Appendable) 

EDIT: As for your example, I don't understand why it will fail. My test is almost identical and works without any problems. What does the signature of process.consumeProcessOutput look like? Alternatively, you can double-check that MyClass$1 implements Appendable by running javap MyClass$1 .

+6
source

As a complement to @ataylor's solution above , you can use Map as Appendable , but this is a bit of a fancy:

Given the test function:

 def testAppendable(Appendable appendable) { println "appendable = $appendable" appendable.append('a' as char). append("GROOVY",1,2). append("TIM") } 

We can build our appendable as follows:

 def app app = [ append:{ a, b=null, c=null -> if( a.grep( CharSequence ) ) a = a[ (b?:0)..<(c?:a.length()) ] println "Got $a" app } ] as Appendable 

Then execution

 testAppendable( app ) 

Prints out

 appendable = { append=ConsoleScript25$_run_closure1@173a30bd } Got a Got R Got TIM 

as was expected...

Depending on the situation, I would avoid doing it this way, since the route of the anonymous class is much more readable :-)

+3
source

Your anonymous class should be fine. Since all your methods are simply delegated to two other instances of Appendable , you can also implement it as follows:

 final tee tee = { final... args -> app1.append(*args) app2.append(*args) return tee } as Appendable 

The * operator calls Groovy to call #append with the contents of args as its arguments.

MissingMethodException you get because #consumeProcessOutput takes two arguments: one for STDOUT and one for STDERR. It also reads enough from the output to prevent the process from being blocked, so this is probably not what you want here. Instead, try #waitForProcessOutput .

 final app1 = new StringBuilder() final app2 = new StringBuilder() final tee tee = { final... args -> app1.append(*args) app2.append(*args) return tee } as Appendable final cmd = 'ps a' final p = cmd.execute() p.waitForProcessOutput tee, tee println '*' * 80 println app1 println '*' * 80 println app2 
+1
source

this works in recent indigo:

 List l=new LinkedList() { { add(new Integer(1)); add(new Integer(2)); } }; println l 
0
source

Source: https://habr.com/ru/post/900082/


All Articles