Error while executing groovy script

Code is a follows:

class Book
{
     private String title
     Book (String theTitle)
     {
         title=theTitle
     }
     String getTitle()
     {
         return title
     }
}
Book gina=new Book('Groovy in Action')
assert gina.getTitle()=='Groovy in Action'
assert getTitleBackwards(gina)=='noitcA ni yvoorG'
String getTitleBackwards(Book)
{
    title=book.getTitle()
    return title.reverse()
}

When I execute is with Ctrl+R, I get the following compilation error.

1 compilation error:

Invalid duplicate class definition of class Book : The source Book.groovy contains at least two definitions of the class Book. One of the classes is an explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name. at line: 1, column: 1

Can anybody please explain me what is happening here.


Solution 1:

Invalid duplicate class definition of class Book:

The code listing of the OP contains two parts:

  1. The type definition of class Book
  2. A groovy script that acts as a client of the Book type

Groovy treats your *.groovy file as either a script file or as a class definition file. A script file is a file that contains code that is not inside a class definition. When Groovy compiles a script file it implicitly creates a class to hold your code and the implicit class is given the name of the Book.groovy file.

Then, the compiler will try and create an additional class Book for the Book class defined in the groovy script, and the error occurs here because now there a actually two Book class definitions.

Compare: Blog entry with code sample for this error message

A way to define the Book class and the client script in the same file would be to rename the file, e.g. to BookApp.groovy. Caveat: if you do this, the Book type can only be referenced from within the script file, the Book type would not be found by groovy automatically, even if the *.groovy file was found on the class path.

Solution 2:

  1. Groovy console buffers items (sources, classes, variables) internally, second click of "run" can be different that first, I agree. Almost all interpreter windows (in any languages) has similar behaviour
  2. has delicate differences when opening from File, pasting into window without file, in consequence can have name Book or ConsoleScript1 etc ("procedural" use of Groovy has hidden "object" background, hidden/default/generated class names from file etc)

This can be help-full by ad-hoc programming (script mode) but not always is the best for true OOP.

PS. code has few errors, too