How to understand Groovy's classes as first-class citizens - groovy

I am an experienced Java developer, but a novice Groovy programmer, which I am learning at the moment (and it's great so far). As a reference I am reading this document:
http://groovy.codehaus.org/Groovy+style+and+language+feature+guidelines+for+Java+developers
That is all fine, except one thing I do not fully understand. The documentation says that classes are first-class citizens and the .class suffix is not needed in Groovy. But if that is the case how can I then refer to an object's type (i.e. class) in Groovy?
Consider the following example:
def o = new Object()
println("$o, ${o.class}")
Which gives me the following output:
java.lang.Object#da479dd, class java.lang.Object
This output is expected and makes sense. But what is the Groovy documentation than referring to when they say that the .class suffix is not needed?

In Groovy and many other dynamic languages everything is an object, including class itself.
Say you have a class Circle in java. You need to call Circle.getClass() for an class object do deal with. In many dynamic languages, class itself does not need to be specified. Say you have a class
class Miu {}
and each later reference to Miu will be referencing to the class object itself
Miu.class
Miu
will both evaluate to the very same object
In other words, Java and earlier in C++ had no eval(), so class definition itself cannot be made into class object directly. OO model in them is more like class oriented programming rather than true object oriented, as classes are subtly not objects. In more recent interpreted dynamic languages classes themselves are directly objects.

You're confusing two different things. You don't need .class when you're referring to some particular class, so if you have a class Foo and you want to refer to it you don't have to type Foo.class, you just type Foo. (That's what the article you're linking to describes.) But when you have some object and you want to know its class you would still use .class (where .class is actually short for invoking the getClass method). Note if you have a map and you want to know its class you have to type out getClass() so it won't think you aren't referring to a map key called 'class'.

Related

Creating libraries that can be imported and used in Groovy

Currently, I am working on a project to transpile from my company's in house scripting language, which is Object Orientated and takes quite a few features from other languages, into Groovy, which has many similar features.
To keep code as close to original as possible, I am trying to leave certain function names and parameters the same. To cater for this, I would like to write a set of libraries that can be imported.
For example, say I have an inbuilt method in the original scripting language,
I would like to be able to write the definition for this method in a groovy file, that can then be imported when needed, and the method may be called.
Tools.groovy
// filename: Tools.groovy
public String foo(String bar) {
return bar;
}
and in another file
Main.groovy
// filename: Main.groovy
import Tools;
String bat = foo("bar")
I know you can can compile class files into jars and put them into the class path, but a lot of the methods I will need to implement will either require meta programming or won't be associated with an object.
Sorry if it's either a bad question or not clear enough. I'm not sure whether its even possible.
Cheers
I believe you should be able to create libraries and reuse them when needed.
All you need to do is create class and add the static methods if you do not have to create instances, non static methods otherwise. Then it looks like you already aware how to proceed later.
For instance, you can create utilities classes for String, List, etc based on your description.
By the way, even if you do not create libraries, it is even possible to write one lines in groovy achieve what you may needed most of the cases.

Get a list of all the arguments a constructor takes

Is it possible to get a list of all the arguments a constructor takes?
With the names and types of the parameters?
I want to automatically check the values of a JSON are good to use for building their equivalent as a class instance.
Preferably without macros... I have build a few, but I still find them quiet confusing.
Must work with neko and JS, if that maters.
Thanks.
I think you want to look at Runtime Type Information (rtti)
From the Haxe Manual: The Haxe compiler generates runtime type information (RTTI) for classes that are annotated or extend classes that are annotated with the #:rtti metadata. This information is stored as a XML string in a static field __rtti and can be processed through haxe.rtti.XmlParser. The resulting structure is described in RTTI structure.
Alternative; If you want to go with macros, this might be a good start
http://code.haxe.org/category/macros/add-parameters-as-fields.html

Reserved Class Names in Groovy

If I have a class named Character.groovy (with no explicit constructors) and try to instantiate it, I get a message that says:
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.lang.Character()
But if I change the class name to Characterr.groovy, then I am able to instantiate an object and use it as expected. So are there reserved words I can't use in Groovy classes? If so, why is Character one of them?
It's not a reserved class name, but there already is a class with that name (java.lang.Character) imported as the package java.lang gets imported automatically in java.
This can happen all the time, especially if you are a java developer and not used to get e.g. java.io package etc. autoimported for you by groovy (e.g. File) (see also What packages does 1) Java and 2) Groovy automatically import?)
There are three ways around it:
the java way: address your class with the full name, that is package and class name. e.g. org.myrpg.Character.
the groovy way: import the class with a new name. e.g. import org.myrgp.Character as RPGChar and use then RPGChar instead.
the zen way: more often than not, it is not worth the hastle and easier to just rename your class. if you tripped over this once, then the chance very high you will trip over this again and only things like #CompileStatic or an IDE may make notice you this at compile time or while writing it.
http://groovy.codehaus.org/Reserved+Words
Those are the reserved keywords
http://docs.oracle.com/javase/8/docs/api/java/lang/Character.html
Character I believe is a object wrapper class in java which is why you can't use it. You can't use any name of java classes that are autoincluded in java

Make groovy metaclass methods available globally

I have a groovy script, Bootstrap.groovy, where I have defined several metaclass methods on the String class. I have my test cases in another file Test.groovy. How do I make the metaclass methods available in the Test.groovy, when manipulating String? (Iow, how do I make the metaclass methods globally available in other scripts/programs)?
(I did search and find some related questions, but they did not answer this specifically. Im using Groovy 1.8.4)
Use the DelegatingMetaClass to make these additions to the String class globally visible.
I think I found a way to do this: just call evaluate(new File("ch8/Bootstrap.groovy")) in Test.groovy. Previously I was trying new GroovyShell().evaluate(), but thats not required. I could directly call the evaluate() method.

Is there a "use strict" for Groovy?

I remember from my Perl days the "use strict" statement that cause the runtime to do extra validations. Is there an equivalent for Groovy?
I do not enjoy being bitten during runtime by what can be detected on compilation, like passing too few arguments to a constructor.
Groovy 2.0 now has optional static type checking. If you place a #groovy.transform.TypeChecked annotation on a class or method, groovy will use strict, Java-like static typing rules.
In addition, there's another annotation #groovy.transform.CompileStatic that is similar, except it goes a step further and actually compiles it without dynamic typing. The byte code generated for these classes or methods will be very similar to straight Java.
These annotations can be applied to an individual class or method:
import groovy.transform.TypeChecked
#TypeChecked
class MyClass {
...
}
You can also apply them globally to an entire project without adding annotations to the source files with a compiler config script. The config script should look something like this:
withConfig(configuration) {
ast(groovy.transform.TypeChecked)
}
Run groovy or groovyc with the -configscript command line option:
groovyc -configscript config.groovy MyClass.groovy
There's more information in the Groovy manual:
http://groovy-lang.org/semantics.html#static-type-checking
http://groovy-lang.org/semantics.html#_static_compilation
Is there an equivalent for Groovy?
Not that I know of.
I do not enjoy being bitten during
runtime by what can be detected on
compilation, like passing too few
arguments to a constructor.
Then Groovy is probably the wrong language for you and you should use something like Java or C# instead. Alternatively, there is a version of Groovy, known as Groovy++ which has much stronger type-checking, but I don't consider it sufficiently mature for production use.
IntelliJ (and possibly other IDEs) provides a lot of warnings about dodgy Groovy code. Although these warnings don't prevent compilation, they almost give you the best of both worlds, i.e. the safety of a static language and the flexibility of a dynamic language
No, there is no such thing, and there can't be. Perl's "use strict" only prevents the use of undeclared variables (and some very Perl-specific things that I don't think have equivalents in Groovy).
In dynamic languages like Groovy, "passing too few arguments to a constructor" is fundamentally not something the compiler can detect, because class definitions can be changed at runtime via metaprogramming. Also, you usually don't have the type information necessary to know what class to look at.
If you want maximum compile-time checks, use a statically typed language with no metaprogramming, i.e. Java.

Resources