Getting Groovy With "with" Thursday, November 13, 2008

UPDATE 12/15/2008: I committed a change yesterday that changes the behavior of the .with method to use DELEGATE_FIRST as the resolveStrategy instead of OWNER_FIRST. If you are not sure what that means, you should by the end of this post.

Strange enough title.

Let's start with a hypothetical conversation between a geeky developer and his much less geeky wife:


Jeff: Betsy, how are you?

Betsy: I am fine thanks. How are you?

Jeff: Betsy, I am fine thank you.

Betsy: Great.

Jeff: Betsy, you know my birthday is the day after tomorrow right?

Betsy: Yes, I haven't forgotten. You mention it about 9 times a day you know.

Jeff: Betsy, yes I know. Are we going to have an ice cream cake?

Betsy: Yes, I think that would be good.

Jeff: Betsy, are you going to buy me the new Opeth DVD?

Betsy: I will get it for you but that music sucks big time.

Jeff: Betsy, that is awesome. Thank you.

Betsy: Why do you keep saying "Betsy" at the beginning of every sentence?

Jeff: Betsy, I guess I am used to inflexible languages which aren't very expressive.


Um, what does any of that have to do with Groovy? Well, lets talk about the problem with this conversation (aside from the lady's lack of appreciation for Swedish heavy metal). What is wrong is Jeff begins each sentence with "Betsy". Why might he do that? One reason is so Betsy knows that he is talking to her. Clearly this isn't necessary. It isn't necessary because she already knows he is talking to her. A context has been established which makes the addressing unnecessary. Jeff began the conversation by addressing Betsy, they probably made eye contact and were in close proximity. Once the conversation started, there isn't much question about who each sentence is being directed to.

Again, what does any of that have to do with Groovy? Lets press on...

Consider the following Java code which prints out a specific date.


// PrintIndependenceDay.java

import java.util.Calendar;
import java.util.Date;

public class PrintIndependenceDay {

public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, Calendar.JULY);
calendar.set(Calendar.DATE, 4);
calendar.set(Calendar.YEAR, 1776);
Date time = calendar.getTime();
System.out.println(time);
}
}


Groovy developers can look at that and find quite a bit of noise that doesn't really have anything to do with what the code is trying to do but I want to focus on one specific thing. That one thing is all of the interaction with the calendar variable. Notice that we call clear() on the calendar, then call set() several times and later call getTime() on that same variable. All of those calls are prefixed with "calendar." so the compiler knows what we want to do. If we called "clear()" instead of "calendar.clear()", what would that mean? Are we calling the clear() method in this class? If that was our intent, it would not work because there is no clear() method. We have to prefix the call with an object reference so the compiler knows where to send the request. That seems to make sense. However, if we are going to do a bunch of things "with" the same object, wouldn't it be kind of nice if we could somehow do all of those things without all the repetition. Specifically, it might be nice if we could get rid of all of those "calendar." prefixes.

On to Groovy...

The following Groovy code does the same thing that the Java code above does.


// PrintIndependenceDay.groovy

def calendar = Calendar.instance
calendar.with {
clear()
set MONTH, JULY
set DATE, 4
set YEAR, 1776
println time
}


Wow. That is a good bit cleaner than what we started with. Part of the reason for that is we were able to get rid of all of those "calendar." prefixes. What allowed us to do that is calling the "with" method on the calendar object and passing a closure as an argument. What we have done there is establish a context that says "do all of this stuff with this calendar object". When the closure executes, the calendar is given an opportunity to respond to method calls like clear() and set() and the implicit call to getTime() when referring to the "time" property which is being passed to println. Likewise, the references to MONTH, JULY, DATE and YEAR properties are also being handled by the calendar object.

That is pretty slick. Lets dig just a little deeper to get a little better understanding of what is really going on.

Groovy closures have a delegate associated with them. The delegate is given an opportunity to respond to method calls which happen inside of the closure. Here is a simple example:


// define a closure
def myClosure = {
// call a method that does not exist
append 'Jeff'
append ' was here.'
}

// assign a delegate to the closure
def sb = new StringBuffer()
myClosure.delegate = sb

// execute the closure
myClosure()

assert 'Jeff was here.' == sb.toString()


When the closure is executed, those calls to append() in the closure end up being sent to the delegate, the StringBuffer in this case.

Something similar is happening in the Groovy calendar code above. A closure is being passed to the with() method. That closure is calling methods like set() and getTime() which don't really exist in that context. The reason those calls don't fail is the with() method is assigning a delegate to the closure before it is executed. The delegate being assigned is the object that the with() method was invoked on. In the calendar example, the delegate is the calendar object. Something like this is happening...


def closure = {
clear()
set MONTH, JULY
set DATE, 4
set YEAR, 1776
println time
}
def calendar = Calendar.instance
closure.delegate = calendar
closure()


This code does the same thing as the first Groovy example. Obviously the first one is cleaner.

I sort of lied a bit, or at least left out a detail that may be significant. The closure that is being passed to the with() method is really being cloned and it is the clone that is assigned the delegate and executed. This is a safer approach than monkeying with the original closure. If the reasons for that aren't clear, the explanation is another story.

Another bit of info that is missing here is the strategy that a closure uses to decide when to send method calls to the delegate. Each Groovy closure has a resolveStrategy associated with it. This property determines how/if the delegate comes in to play. The 4 possible values for the resolveStrategy are OWNER_FIRST, DELEGATE_FIRST, OWNER_ONLY and DELEGATE_ONLY (all constants defined in groovy.lang.Closure). The default is OWNER_FIRST. Consider the owner to be the "this" wherever the closure is defined. Here is a simple example...


class ResolutionTest {

def append(arg) {
println "you called the append method and passed ${arg}"
}

def doIt() {
def closure = {
append 'Jeff was here.'
}

def buffer = new StringBuffer()

closure.delegate = buffer

// the append method in this ResolutionTest
// will be called because resolveStrategy is
// OWNER_FIRST (the default)
closure()

// give the delegate first crack at method
// calls made inside the closure
closure.resolveStrategy = Closure.DELEGATE_FIRST

// the append method on buffer will
// be called because the delegate gets
// first crack at the call to append()
closure()
}

static void main(String[] a) {
new ResolutionTest().doIt()
}
}


So you see how the with() method helps establish a context where a bunch of things may happen "with" a specific object without having to refer to that object over and over. This can help clean up code like the Java code we started with. This approach can also be really useful when building a domain specific language in Groovy, a topic for another time.

Enjoy! :)

Grails Training In Chicago Monday, August 04, 2008

We are really excited to have a 3 day Groovy/Grails training event coming up in Chicago later this month. The training dates are August 26-28. The training will be held at the Hotel Indigo in Palatine.

This is 3 days of lecture and reinforcing lab work. Attendees should expect to write a lot of Groovy and Grails code with your training expert. There is no better way to quickly get your team up to speed on the technology, well beyond the basics.

As with all G2One training events, students will receive a free 12 month license to use IntelliJ IDEA. The IntelliJ guys have done a fantastic job of building first class Groovy and Grails support for the IDE.

For a full course outline and more information, please visit http://g2one.com/training/. Any questions may be directed to training@g2one.com.

G2One QuickCast Site Launched! Wednesday, July 30, 2008

G2One have launched the G2One QuickCast site. A G2One QuickCast is fast and furious little movie demonstrating something interesting about the Groovy language and/or the Grails framework.

The first movie available there demonstrates how powerful tools like Grails and Git can work together to support a really really agile development process. Watch this movie and try to do something like this with your web framework and your VCS. If you can't, your tools are not flexible enough. :)

Enjoy!

G2One Groovy Grails Training In North America Monday, July 14, 2008

G2One have announced our Groovy/Grails North American public training schedule for the rest of the year. The schedule is available at http://www.g2one.com/training/.

Our training events are a fantastic experience. G2One are the folks who lead and sustain the development of both Groovy and Grails. No one understands the technology better than the people who build it. G2One training events give developers an opportunity to spend several days with a technology expert covering everything from fundamentals to advanced language and framework features. The sessions include a perfect mix of lecture and reinforcing lab work. That hands on approach is a great way for developers to internalize the details. There is no better way to quickly get a team up and running with the technology.

Grails Plugin For Hudson Thursday, June 19, 2008

I am pleased to announce that we have worked up a Grails plugin for Hudson. Hudson is a really slick continuous integration server. Check out their site for more info on the engine itself.

It has always been possible to build Grails apps from Hudson but in the past this has involved writing shell scripts that are triggered by Hudson. This works but is not the slickest solution. What you really want is for the CI server to have knowledge of the fact that the project you are building is a Grails app and that knowledge will allow the tool to be more efficient about carrying out the build and also allow the CI server to provide Grails specific options for the build. This is where the new Grails plugin is heading.

Right now the plugin is very basic. In the system configuration screen you may configure as many Grails installations as you like. This is useful for situations where the same CI server may be building multiple projects with different version of Grails or maybe even building multiple copies of the same project with multiple versions of Grails. Below is a screenshot of the system configuration screen:



Notice that there is built in validation to make sure you have entered a valid path to your Grails installation.

When configuring a project in Hudson you have a lot of options for what should happen at build time. The Grails plugin adds a "Build With Grails" option and if that option is selected you can select from a list of common build targets to execute as well as type in any arbitrary targets you may want to execute. This is useful for executing Grails commands that are not in the list of checkboxes and for executing your own custom Grail scripts that may be part of your project. Below is a screenshot of the project configuration screen:



The first version of the plugin has not been released yet but will be soon. In the meantime, I would be happy to hear what kinds of capabilities you would like to see the plugin provide. Even in its current very basic state, the plugin is very useful as it makes configuring a Grails project in Hudson drop dead simple.

St. Louis Dynamic Language Interest Group Saturday, June 07, 2008

I have created the St. Louis Dynamic Language Interest Group at LinkedIn. If you have a special interest in dynamic languages and are in the St. Louis area or are close enough to the St. Louis area that you would like to be involved with the group, please take a minute to visit the group at LinkedIn and join us.

More information is coming regarding the goals of the group and what sorts of activities we may engage in. I want to give the group some time to populate before moving forward with those details.

If you have any questions about the group in the meantime, please don't hesitate to let me know.

Jeff Brown
Director - North American Operations
http://www.g2one.com/

New Grails Mail Plugin Wednesday, June 04, 2008

The new Grails Mail Plugin is really slick stuff. Very little effort has gone in to the thing so far and there is more to come but even in its current state this is really nice. More details are available at http://grails.org/Mail+Plugin but basically you get a method called 'sendMail' added to your controllers (or you could use an autowired mailService) that accepts a closure and the contents of the closure express the details of the message being sent. A simple example looks like this...


sendMail {
to 'fred@g2one.com'
subject 'Hello Fred'
body 'How are you?'
}


Take a look at the docs for more information. This is good stuff already. I think the simplicity of sending a message like this is pretty impressive but more impressive is how easy it is to build support for something like that in a dynamic language like Groovy. More and more folks are taking advantage of the Grails Plugin System to easily add capabilities like this to their web apps.

Enjoy!

Groovy Grails Training From G2One and Callista Enterprise Wednesday, May 21, 2008

G2One, Inc. and Callista Enterprise AB have announced a partnership to support Advanced Groovy and Grails training in Scandinavia.

Göteborg 2008-09-08
Stockholm 2008-09-15
Malmö 2008-09-22

The 3 day comprehensive course covers details from intro to advanced for both the Groovy language and the Grails framework. The course description may be found here.

As with all G2One training events, students will receive a free 12 month license for IntelliJ IDEA. IDEA's JetGroovy brings fantastic support for both Groovy and Grails to the IDE.

Please contact us at training at g2one dot com with any training related inquiries.

North American dates coming soon...

Pre JavaOne Groovy/Grails Meetup Next Monday Wednesday, April 30, 2008

We have been busy preparing for JavaOne and it is finally almost here. Yay!

We hope to see you at the G2One / NFJS Meetup Monday night. Click the link for all of the details and be sure to click the "register" link. Registration is free and the event promises to be a load of fun. Come hear the latest Groovy and Grails news from G2One, the latest word from the respected NFJS tour and finally a great expert panel discussion. Author signed copies of Scott Davis' Groovy Recipes book and Venkat Subramaniam's Programming Groovy book will be raffled off.

Don't miss it.

Between now and then, I hope to see some of you in Denver this weekend. :)

Another Big Week For Groovy And Grails Monday, February 18, 2008

This is definitely going to be another big week for Groovy and Grails. The Grails 1.0.1 point release was published today. This release contains over 40 enhancements over the 1.0 release from just a couple of weeks ago. The Grails community has been buzzing at full steam since the 1.0 release. This is fantastic stuff!

This Wednesday I am heading to the great New York City to speak at their JUG about Groovy. That is going to be a lot of fun. Immediately after that is the event that so many people (including myself) have been looking forward to for a long time. That of course is The Groovy Grails Experience in Reston Virginia, starting on Thursday Feb. 21 and running through Saturday the 23rd. It will be a while before this many of the key players in the Groovy/Grails community get together in one spot to talk shop. I can't wait!

Jeff Brown Interview At Groovy Zone Saturday, February 09, 2008

I had the great pleasure of doing an interview recently with Steven Devijver for The Groovy Zone. Today, that interview was published. Check it out at http://groovy.dzone.com/news/jeff-brown-grails-10-and-beyon. In the interview we discussed the Grails 1.0 release, the great plugin story that Grails has to offer, the upcoming Groovy Grails Experience and more. I want to thank Steven for the opportunity.

The Groovy And Grails Communities Continue To Buzz Thursday, February 07, 2008

A lot of things are going on right now in the Groovy and Grails communities. I have been really busy myself and have a lot of exciting things coming up. I am very excited about my role as Director of North American Operations with G2One and that is really keeping me busy.

I spent the first part of this week out in Silicon Valley with Graeme Rocher and Peter Ledbrook working on some really exciting Grails stuff. It was great to be out there with Graeme on the day that Grails 1.0 was released. The whole development team and user community have done an incredible amount of work on Grails to get to this point but I think Graeme himself deserves the props. Graeme conceived the thing and has been driving it very hard from the beginning with the focus and vision necessary to get the framework to this point. Well done Graeme!

Later this month I am going to have the pleasure of speaking at The New York Java SIG about Groovy. I speak at JUGs all the time but this one in particular I am looking forward to. A few months ago I was on the schedule to speak out there and due to an incredible string of bad luck, I wasn't able to make it. My flight was cancelled. My replacement flight was delayed. Once my delayed flight took off we ended up circling in the air for a long time waiting for some weather to settle down. Once I got to New York we found it near impossible to get in to Manhattan because it just happened this was the day of the huge water main explosion. I ended up spending the entire day on airplanes and in terminals just so I could get to my hotel, sleep and then fly home the next day. This time, things will no doubt go much more smoothly. I can't wait to get out there.

When I leave the New York Java SIG I will be heading straight to the airport to get to the event that I am even more excited about. That is The Groovy Grails Experience in Reston VA beginning on Feb. 21. The event is being put on by the same folks who have been putting on the hugely successful No Fluff Just Stuff symposiums for years now so I know it is going to be a great event. This is 3 days packed with talks all about Groovy and Grails. Of all the shows I do this year, this is probably going to end up being the one that is most exciting for me personally. All of my friends from the Groovy and Grails communities are going to be there and I know everyone is going to have a great time. This is the biggest Groovy/Grails event ever to be put together. It isn't often that we get an opportunity like this to get together so many players in the Groovy/Grails communities to talk about the technology. For folks who are interested in the power of Groovy and Grails and the vast possibilities that dynamic languages bring to the JVM, I can't think of a better way to spend 3 days. I am completely pumped about this event.