2010/06/15
Groovy closures combined with iterators make it simple to create our own enhanced iterators that let us process a collection how we want to.
I write my own custom iterators all the time and name them something descriptive. This makes the code much more readable. Rather than trying to decipher what a for loop is trying to do, we wrap up all of that iteration logic into a meaningful name and we cleanly separate that iteration from the processing that we’re doing with each element.
This kind of design is a core concept in Uncle Bob’s Clean Code, one of my favorite programming books in the last few years.
This example iterates over a collection and calls the passed in closure until we hit a value greater than 5.
def eachUntilGreaterThanFive = { collection, closure ->
for ( value in collection ) {
if ( value > 5 ) break
closure(value)
}
}
def a = [1, 2, 3, 4, 5, 6, 7]
eachUntilGreaterThanFive(a) {
println it
}
prints:
This code makes it obvious what the iterator is doing (looping till we hit a condition) as well as what will happen with each element iterated over (print it out).
For a real life example, I had a need to iterate over a list of values and where I needed both the current object as well as a peek at the next object in the list.
Doing this is Java is a bit of a pain, but groovy makes it easy to write and (hopefully) to read, we can also add it directly onto the Collection metaClass so that it’s available for all of our Collection instances:
Collection.metaClass.eachWithPeek = { closure ->
def last = null
delegate?.each { current ->
if (last) closure(last, current)
last = current
}
if (last) closure(last, null)
}
These test cases show that as we iterate through the collection, we can see the current item and peek at the next one (if any). If the collection is empty, we don’t execute the closure it, and if we’re at the end of the list there isn’t anything to peek at:
[].eachWithPeek { current, peek ->
assert false // shouldn't get here, nothing to iterate through
}
[1].eachWithPeek { current, peek ->
assert current == 1
assert peek == null // only 1 element, nothing to peek at
}
def results = []
[1, 2, 3, 4, 5].eachWithPeek { current, peek ->
results << [current, peek]
}
assert results == [[1, 2], [2, 3], [3, 4], [4, 5], [5, null]]
2010/05/7
At work, we’re using mercurial for our source control. As we’ve released code to production we’ve needed to branch our repository to support what’s in production as well as ongoing development.
By default, grails uses ~/.grails as the working directory. If you’re doing branchy development, you can run into problems with this if you’ve got plugins installed in one branch that aren’t in the other. Having a unique directory per branch prevents you from having to run grails clean all the time.
Here’s a quick shell script that changes the grails working directory to have the branch name as a suffix if your source is contained in a mercurial repository (ex: the default branch would be ~/.grails_default and the 1.0 branch would be ~/.grails_1.0). If your application is not in a repo, it just uses the regular ~/.grails directory.
#!/bin/sh
HG_BRANCH=`hg branch 2>/dev/null`
GRAILS_SCRIPT=$GRAILS_HOME/bin/grails
if [ $HG_BRANCH ]; then
GRAILS_WORK_DIR=`echo ~`/.grails_$HG_BRANCH
echo "** grails working directory: $GRAILS_WORK_DIR"
$GRAILS_SCRIPT -Dgrails.work.dir=$GRAILS_WORK_DIR $@
else
echo "** default grails working directory"
$GRAILS_SCRIPT $@
fi
Just save this script as “grails” and put it in your PATH before the $GRAILS_HOME/bin directory (also make sure that you’ve defined $GRAILS_HOME). I have a ~/bin directory that’s the first thing in my PATH.
If you use the grails-debug command, you can repeat these steps for that, just change GRAILS_SCRIPT to $GRAILS_HOME/bin/grails-debug.
This same technique could easily be modified to be used for other source control systems such as git or subversion.
2010/04/4
Version 1.1 of the build-test-data plugin has just been released.
It adds a new buildLazy method that will only create a new object graph if it can’t find an existing object that matches the build criteria specified.
Example:
def a = new Author(firstName: "Ray", lastName: "Bradbury")
a.save()
assert 1 == Author.count()
// Author table already has Ray Bradbury in it, finds existing record
def bradbury = Author.buildLazy(lastName: "Bradbury")
assert 1 == Author.count()
assert bradbury.firstName == "Ray"
def newAuthor = Author.buildLazy(lastName: "Moore")
assert 2 == Author.count() // creates a new record, no existing "Moore" author previously
I find this particularly useful for building testing data in the grails console. It allows me to do some quick setup of new objects and then concentrate on creating the code that I actually want to try out. Without buildLazy, I was always commenting out my creation code so that multiple executions of the test script didn’t create multiple copies of the same data (and potentially hit unique constraints issues that I had to screw around with).
Now, I no longer need to worry about commenting out the creation code after running it the first time.
Example:
def u = User.buildLazy(ssn: "123-456-7890") // User.ssn has unique constraint
u.foo()
u.bar()
u.baz()
Before buildLazy I’d need to comment out the user creation and replace it with a user.findBySsn. Now buildLazy does the creation and later finding for me. I can concentrate on making foo/bar/baz do what I want them to (the reason I opened the console in the first place).
2010/03/17
I’ve finally released version 1.0 of the grails build-test-data plugin.
If you’re not familiar with build-test-data, the quick summary is that it puts a build() method on all grails domain objects. Calling that method will automatically construct and save an instance of that domain object that conforms to all of the domain’s constraints. It also allows you to override the values that you want to explicitly set. It makes your tests much cleaner and less fragile as you only need to specify the values that actually matter to a particular test method instead of building a huge graph of objects just to satisfy constraints.
The plugin has been quite stable for the past 6 months or so, and has survived upgrades from grails 1.0.X through grails 1.2.1 with minimal changes. Because of this, I’ve decided to move the version from 0.2.3 to 1.0 to indicate that the plugin is stable and ready to be used. I’ve also added the LICENSE file releasing the plugin under the Apache 2.0 open source license (the same license as grails). It was always open source, but I had neglected to add the official license file in the past.
If you’re not familiar with the build-test-data plugin, the documentation on the wiki is thorough, I’ve also given a presentation on build-test-data that explains why it’s better than other existing data generation technologies.
The biggest changes for this release compared to the last are a number of bugfixes around making sure that both sides of a one-to-many relationship get populated correctly and that there isn’t a need to refresh() from the database.
Previously, if you had an Author that hasMany Books, and each Book belongsTo an Author, you’d need to refresh the Author if you tried to build a new book with an existing author:
Author eap = Author.findByName("Edgar Allan Poe")
Book b = Book.build(author: eap, title: "The Tell-Tale Heart")
assertEquals eap.name, b.author.name // works, linked in OK previously
assertEquals 1, eap.books.size() // FAILED previously WORKS now, previously the book wasn't added properly to the author side of things
The previous workaround was to call eap.refresh() to reload the author from the database, or to have the user manually addToBooks(b). Both solutions were ugly and kludgy and this issue has now been fixed.
2010/03/2
A couple of years ago, I created a grails auto-completion script for bash and zsh.
Since then, I’ve completely abandoned bash, in favor of zsh (which I consider to be the superior shell) and I’d been getting annoyed at a few issues in the last grails autocomplete script.
I finally got motivated to make some enhancements to it. Including support for grails 1.2 plugin scripts (1.2 moved the plugins into the ~/.grails directory), and support for test class name autocompletion (very useful for grails test-app).
To get it working (assuming you’re using zsh), you can either add the contents of my zshrc_grails_compinstall to your .zshrc file, or you can switch over to using my full zshrc setup, which has a number of nice features that I’ve collected over the years. I’ll also continue to update this as I think of new tricks.
After getting it installed, just type “grails” followed by a space and then hit tab. It will show you a list of all of the potential grails scripts for the application that you’re in. It’s aware of the version of the current app, as well as it’s application name based on the contents of application.properties, and also will include any scripts for the plugins you have installed in that app in ~/.grails/GRAILS_VERSION/projects/APP_NAME/plugins (in addition to the scripts in ./scripts, $GRAILS_HOME/scripts and ~/.grails/scripts).
After you choose your script (such as grails test-app hit space again and it will show you all of the test classes, with the full package for the class, under your test directory.
2010/02/7
Overall, I’m pretty happy with Numbers.app (part of Apple’s iWork suite) as a replacement for Excel. It’s considerably cheaper and has lots of user interface tweaks to make it more pleasant to work with.
One of these changes is that each sheet can actually have multiple tables on it, and these can be arranged independently on the same page. This prevents the problem that happens in excel where you have multiple sets of data you want to see at the same time, but the cell/row sizing for one set of data affects the data in the other set that happens to be on the same row.
I’ve been leveraging this for a one-off personal project and I had a need to sum up all of the data in the 2nd column on all of the tables within a particular sheet.
This brought me to AppleScript, Apple’s scripting language that’s used to drive applications.
Read the rest of this article »
2010/01/24
Inspired by this question on stackoverflow, I decided to create a utility class that allowed me to determine generically what calls a closure makes (without actually letting it make any calls). This lets me see what it’s trying to do before letting it actually do it.
Read the rest of this article »
2009/12/21
This past weekend, I saw @wakaleo running into some issues getting bitbucket hooked up to hudson.
I responded with a long reply that I thought would be worth cleaning up and posting here.
Read the rest of this article »
2009/11/8
This past week, I gave a presentation to the DevJam meeting on the advantages of using Mercurial, a DVCS (Distributed Version Control System) over tools like Subversion, Perforce, and ClearCase.
Read the rest of this article »
2009/11/3
A while ago I blogged about my grails testing aliases and how much time they save me.
I’ve made some enhancements to them in the interim that have made them even easier to use.
The most important alias is gtaf, which is short for “grails test-app” for failed tests.
It will search through your test output directory and look for any tests that failed. If it finds any, it will rerun only those tests. Otherwise, it will rerun all tests. That makes it easy to just use gtaf all the time. If any tests fail, it will open them up using Console.app.
If you’re not on OSX, or would like to use something else to view the failed test logs, just modify the testlog alias to do something different.
Read the rest of this article »