Tuesday, December 1, 2009

Groovy, you're great, but keep it private please..

If you're a Java coder, by now you've certainly wished something like this: "I wish Java had this of Ruby.. I wish it had that of Python.. that of Smalltalk" and similar. I came across the Groovy language just a few days ago and I started to enjoy its features immediately. It brings together the best features of the 3 mentioned languages: Ruby, Python and Smalltalk; all of that built upon Java and its greatness :) Well, frankly I can't say "the best" features, since I'm not into any of the 3 languages, so I don't really know what their the best ones are. But I know, that it is the great things like closures, convenient list and map notations, optional dynamic types and others, that are still missing in Java and it's unclear whether we'll see any of that implemented in Java itself any time soon.

Have you not already done so, let me recommend you to check out the official Groovy web site and go through the brief lists of the language's features. If you do, I bet you will soon find some spare time to dig a little deeper and check it out with your hand on it.

Honestly, I don't know too much about Groovy yet, or better to say, I haven't tried how the particular parts of the implementation work. I haven't found the time to do that yet :) But I've run into some confusing behavior regarding the properties access control of a Groovy class. As stated on the official web site, at the stage of source code compilation, the following are some of the rules that are applied:
  • A name declared with no access modifier generates a private field with public getter and setter (i.e. a property).

  • You can declare a property and also declare your own getter or setter.

  • If you want a private or protected property you have to provide your own getter and setter which must be declared private or protected.
The first two are obvious. You can let the Groovy compiler create getters/setters for you and have your POGOs' (Plain Old Groovy Objects) source size shrink by a great amount. Ok, I know that your IDE generates that code for you (I hope:), you don't have to type it on your own. But how many times do you need to actually see that code? Never, right? You only need to see your customized setters and getters, so why not bother with them only. That's exactly how Groovy works. Plus, in case you need to create other utility methods in your class, you surely appreciate the fact you don't have to scroll over tens of getters/setters trying to find the method you're looking for.

Now, there is a little problem about the third one, or at least most of the developers consider it a problem, from what I've read on various sites lately. In case you need a private field with no getter or setter, which is a common situation, Groovy says: "Just declare the field with the private keyword and you're done, I will not generate any getter or setter for the field in that case!". And it does what it says. The following snippet of code clarifies it:

class Car {
private String color = "blue"
}

def car = new Car()
// the next line fails, the getter does not exist,
// compiler did not create it automatically in this case
car.setColor("yellow")
// the following fails, the getter does not exist, compiler did not
// create it automatically in this case
println car.getColor()

But the problem comes up when you try to access the field directly. The following code will work just fine:

class Car {
private String color = "blue"
}

def car = new Car()
car.color = "yellow" // works fine, no setter is called, the field is accessed directly
println car.color // prints out "yellow", what .. ???


So apparently, private fields can still be easily accessible with Groovy. They shouldn't be, right? It brings down one of the OOP features we all rely on and always use - hiding fields that the others should have no clue about. There are some arguments from the people who like this "feature", that it makes some testing cases much easier. That I can't say anything about, since I don't understand how it helps in that matter and if any of you can explain in a few words, I'd be happy (or I will read some more about that:). Ok, let's say it does help sometimes, but that doesn't change the fact we should have the means of keeping private what we decide to keep private. If not, what would be the point of having and using the keyword "private" then?

Groovy knows about this issue, since many have complained. The current stable version that came out is 1.6.6 and the Groovy team is promising a few breaking changes for the version 2.0, among which should be the "issue of privacy". Well, we will see how they fix it and what the word "fix" will mean this time...

No comments:

Post a Comment