This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I've seen the hype, and I can type the word Groovy into google just fine.
However, can you give a real-world-ish use case that caused you to say "Hey! Groovy made for a better solution than Vanilla Java!"
I tend to write relatively simple webapps based on a Struts/Spring/Hibernate architecture, and have alot of stuff planned out to learn. Why should I put Groovy on that list and/or prioritize it over other items?
The biggest win for me is that Groovy _is_ Java at the end of the day. Groovy was implemented in Java, and was explicitly targeted at Java developers. With few exceptions, you can take a .java file, rename it to .groovy, and it will run without a hitch. Of course, you won't end up with idiomatic Groovy, just Groovy that will execute.
The first thing that drew me to Groovy was the POGOs -- Plain Old Groovy Objects. You can define a bean as quickly as this:
The getters/setters get dynamically created for you. Of course, this class is usable by any Java class -- it literally cannot tell the difference.
There are many more examples that I'm sure that you'll see pop up -- most of them involve drastically reducing the amount of Java code that you have to write and maintain. But my favorite part is that rather than forcing you to scuttle your existing codebase and rewrite it from the ground up in a brand new language, Groovy allows you to leave everything in place and integrate. That is a _huge_ benefit...
Joined: Sep 16, 2007
Hmmm, I may have to take a closer look at Groovy, but not necessarily for the use case you gave.
You state that with a POGO, getters and setters are generated automatically. As an IDEA user, its not as if I actually write the getters and setters out manually (its more like: define variables, alt-insert, generate setters and getters). Since this is automated for me, I'd tend to do it that way and not deal with any particular performance issues (although this one is probably minor).
Well, the virtue of having implicit getters and setters isn't just that you don't have to write them. It's also an issue when you're looking at a class and studying it. Getters and setters are easy to understand, sure, but they also create visual clutter that makes it harder to locate the parts of a class that are actually interesting. I like to open up a class file and immediately see the interesting parts without having to scroll around a lot looking past boilerplate, and languages like Groovy and Ruby are much better for this than Java, I think.
Groovy gives you an easy way to produce code, so you dont spend your time looking at the structures but you work on algorithm, how it should work. At the beginning I didnt like Groovy because it could lead to spaghetti code, mix and match (because you dont have to declare the type of the object ), but this all depends on the programmer. If you are good you can write good and clean programs.
With groovy you can accomplish many task faster than in Java ( see how easy is to work with List, Maps ) or how fast is to create POGOs. You can also expand existing Java classes: adding new functions or modifing them without changing source code ( thanks to ExpandoMetaClass ). However this flexibility makes that Groovy is slower than Java ;/ ( everything is mapped to the Groovy Meta Class ).
For me Groovy syntax is a little similar to PHP but with better Object-Oriented features. ( But I dont want to make a flame war )
One thing I really like about Groovy is the each method. It allows you to iterate over basically anything. Lists, Maps, Ranges, Sets, [insert anything else here]. It's defined on the Object class, so literally everything has an each method.
I like each better than Java 5's for-each statement because with Java you can't always use the for-each. For example, you can't do this in Java:
Why not? You'll get a ConcurrentModificationException (assuming you have something in myList that starts with "foo") because you can't remove an object from a List while you're iterating over it. You'd have to use the old for loop with an Iterator and call the Iterator's remove method. In Groovy, I can always use each for iteration, and I like that a lot. [ April 08, 2008: Message edited by: Josh Brown ]
That's nice of Groovy. Thank you Josh for sharing it
Joined: Jan 30, 2000
[B][Josh]: I like each better than Java 5's for-each statement because with Java you can't always use the for-each. For example, you can't do this in Java:
Why not? You'll get a ConcurrentModificationException (assuming you have something in myList that starts with "foo") because you can't remove an object from a List while you're iterating over it. You'd have to use the old for loop with an Iterator and call the Iterator's remove method. In Groovy, I can always use each for iteration, and I like that a lot.[/B]
Calling myList.remove() is a bad idea here anyway, very inefficient. It's unfortunate that Java (and thus Groovy) throws a ConcurrentModificationException even when there is clearly only one thread involved - that's misleading. But while it shouldn't lead to incorrect results, using the list's remove() is pretty slow compared to using the remove() on the iterator. Especially if more than one item will be removed. So I don't see how Groovy's each() method helps here. It's just another way to iterate, unrelated to the real problem.
A nice alternative would be to simply use findAll() to create a new list without the items you don't like. For example:
I don't see a method that will delete entries from myList directly - instead we create a new list (and optionally replace the old with the new). Often that's preferable anyway. Of course you can just use the Iterator as you would in Java. For comparison, Ruby has a delete_if method that would operate directly on the current list:
Joined: Oct 09, 2007
Good point. I didn't realize that in my Groovy test, I was reassigning myList. Here's what I was doing in Groovy:
This, as you pointed out, is not the same as the Java code I posted, since myList is reassigned. Groovy does in fact throw a ConcurrentModificationException if you try to remove an element from a collection over which you're iterating.
I'm not aware of a Groovy equivalent to your Ruby example, unfortunately.