tags:

views:

72

answers:

3

Is there a way to use anonymous code blocks in Groovy? For example, I'm trying to translate the following Java code into Groovy:

{
  int i = 0;
  System.out.println(i);
}
int i = 10;
System.out.println(i);

The closest translation I can come up with is the following:

boolean groovyIsLame = true
if (groovyIsLame) {
  int i = 0
  println i
}
int i = 10
println i

I know anonymous code blocks are often kind of an antipattern. But having variables with names like "inputStream0" and "inputStream1" is an antipattern too, so for this code I'm working on, anonymous code blocks would be helpful.

+1  A: 

In Groovy, those braces constitute a closure literal. So, no can do. Personally, I'd consider having to give up anonymous blocks for getting closures a very good deal.

Michael Borgwardt
You can use anonymous code blocks in Groovy. See my answer for details and example.
Chris Dail
+1  A: 

What about:

({
 int i = 0
 println i
}).()

int i = 10
println i

I don't have a Groovy installation at hand, but that should do.

OscarRyz
Yes, this works fine. The only drawback when comparing this to Chris's solution above, is that the stack trace is a little messier when an exception happens within the anonymous block. But this is a good solution too, thanks!
piepera
You can also get rid of the .call() and just replace it with ()
tim_yates
I'm curious, does `{int i = 0}.()` works also? ( I mean without the surrounding parenthesis?
OscarRyz
Replacing the .call() with () is valid. Removing the surrounding parentheses is not valid; this results in the "ambiguous expression" compiler error mentioned above.
piepera
+3  A: 

You can use anonymous code blocks in Groovy but the syntax is ambiguous between those and closures. If you try to run this you actually get this error:

Ambiguous expression could be either a parameterless closure expression or an isolated open code block; solution: Add an explicit closure parameter list, e.g. {it -> ...}, or force it to be treated as an open block by giving it a label, e.g. L:{...} at line: 1, column: 1

Following the suggestion, you can use a label and it will allow you to use the anonymous code block. Rewriting your Java code in Groovy:

l: {
  int i = 0
  println i
}
int i = 10
println i
Chris Dail
Well, it's hardly "anonymous" anymore when you've given it a name, is it? :)
Michael Borgwardt
Thanks, this is a little cleaner, and replaces the unnecessary "if else" with an unnecessary label. Slightly more concise.
piepera
@Michael If the label were changed to anon: then maybe no-one will notice :)
crowne