Archive of articles classified as' "shortcut"

Back home

Groovy Each Iterator with Peek-ahead at Next Collection Value

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:

1
2
3
4
5

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]]
1 Comment

Using a Unique Grails Working Directory for each Mercurial Branch

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.

2 Comments

Grails Testing Alias to Rerun Failed Tests

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 »

7 Comments

Poor Man’s “top” for MySQL

2009/06/18

I’m currently working at a startup that’s small enough that we don’t have a dedicated DBA and I’ve been doing a lot of mysql maintenance work recently. I wanted a quick dashboard for which commands were currently running and how long they’ve been running for. Sort of like top but for mysql.

Combining the unix “watch” command with the mysql “show processlist” command gives me what I’m looking for. A quick, self-updating status of the current state of the database.

watch -n 5 --differences "mysql -u username -psekrit -e 'show processlist'"

Shows something like this:

Every 5.0s: mysql -n 5 -u username -psekrit -e 'show processlist'                                   Thu Jun 18 05:25:14 2009
 
Id      User    Host       db      Command Time    State         Info
3141    admin   localhost  mydb    Query   34978   freeing items SELECT id, type, active, email FROM user WHERE email
3146    admin   localhost  mydb    Sleep   0                     NULL       
24876   root    localhost  NULL    Query   0       NULL          show processlist

Where the “time” column is the number of seconds the query has been running, and Info holds the actual query (you can use “show full processlist” to see the full query).

Watch is a nice little linux util that runs a command every “n” seconds (it defaults to 2 seconds). If you use the –differences switch, it will highlight the differences between one update and another. I use watch for all kinds of monitoring activities, such as watching a directory to see a file grow in size as it gets transfered.

Here’s a quick shell function that you can add to your .bashrc/.bash_profile/.zshrc to use on arbitrary hosts:

function mysqltop() {
    MYSQL_OPTS=$@
    watch -n 5 --differences "mysql $MYSQL_OPTS -e 'show processlist'"
}

Then just pass in any creds/host info you need like a normal mysql command:

mysqltop -u ted -psekrit1 -h example.com -P 3307

If you’re on linux, you probably already have “watch” installed. If you’re on OSX, you probably don’t, but you can get it quickly through macports. Install macports, make sure “port” is in your path and run:

sudo port install watch

There is also a command called mytop that you can get which looks like the same thing, but prints out the processlist details with some nicer formatting and a little extra information. It’s in macports, but it has a number of dependencies including mysql so if you didn’t install mysql through macports, you might want to stick with what I have above or get it another way.

(EDIT: updated with bash function)

3 Comments

OSX AppleScript command line util to eject all removable disks

2009/05/26

On my MacBook pro, I’ve got 4 removable hard drives (2 physical in 2 partitions each) and a JungleDisk mount.

I found it painful to manually eject each individual drive in the finder so I threw together this quick AppleScript to eject all the disks.

tell application "Finder"
	eject (every disk)
end tell

Just open up /Applications/AppleScript/ScriptEditor.app and paste that in. Then choose “Save As” and pick “Application”. That will compile the script and create a .app file that you can click on to run, or you can put it in your path and execute it there.

I think the same kind of script could be created with the command line “diskutil eject” command, but this seemed cleaner as I wasn’t able to come up with a generic way to figure out which disks were “ejectable” and which weren’t. AppleScript is able to figure that all out for you.

4 Comments

Shared zshrc file

2009/05/13

Over the years, I’ve had a number of requests for me to share my zshrc file with friends and coworkers. In the past, I’ve normally trimmed out the sensitive parts by hand and then e-mailed the most useful stuff. I’ve always intended to make this an easier process and I’ve finally gotten around to it.

I’ve created a new bitbucket repository to hold my shared zshrc configuration. You can get it for yourself by cloning the repository:

cd ~
hg clone http://bitbucket.org/tednaleid/shared-zshrc/

Read the rest of this article »

3 Comments

Groovy: Enhancement to String class to add a regexp find method

2009/03/28

I just submitted a groovy patch that enhances the String class with a “find” method that makes working with regular expressions much easier.

One of the most common use cases is to search a string for a regular expression pattern. If a match is found, then do something with the matched value.
Read the rest of this article »

4 Comments

Bash/Zsh aliases to switch Groovy and Grails version

2009/03/8

I work on a couple of different grails projects that use a variety of versions of groovy and grails. I’ve thrown together a quick shell script that makes it easy to create a new alias to switch between different versions depending on what project you’re working with.

function switchGrails() {
    echo "Switching to groovy version: $1"
    echo "Switching to grails version: $2"
    sudo rm /usr/local/{groovy,grails}
 
    sudo ln -s /usr/local/$1 /usr/local/groovy
    sudo ln -s /usr/local/$2 /usr/local/grails
    echo "Done!"
    ls -latr /usr/local/{groovy,grails}
}
 
alias g104='switchGrails "groovy-1.5.7" "grails-1.0.4"'
alias g11rc2='switchGrails "groovy-1.6.0" "grails-1.1-RC2"'

You can create your own aliases like the ones above to switch to the groovy/grails combinations that you happen to be working with.

Just stick the code above in your .profile/.bashrc/.zshrc file and restart your shell to make the aliases available.

This function assumes that you’ve got you’ve got groovy and grails installed in your /usr/local directory and that you use a symlink at /usr/local/groovy that $GROOVY_HOME is pointed to and /usr/local/grails that $GRAILS_HOME is pointed to. If those assumptions aren’t correct for you, you’ll have to tweak the script.

It also uses “sudo” as it assumes that /usr/local is owned by root and not by your logged in user. If you’ve chowned the directory to yourself, you can remove the sudo (and the need to enter your password).

Now it’s easy for me to switch between different projects by just typing the appropriate alias:

pollux% g104
Switching to groovy version: groovy-1.5.7
Switching to grails version: grails-1.0.4
Done!
lrwxr-xr-x  1 root  wheel  23 Mar  8 19:55 /usr/local/groovy -> /usr/local/groovy-1.5.7
lrwxr-xr-x  1 root  wheel  23 Mar  8 19:55 /usr/local/grails -> /usr/local/grails-1.0.4
 
 
pollux% g11rc2 
Switching to groovy version: groovy-1.6.0
Switching to grails version: grails-1.1-RC2
Done!
lrwxr-xr-x  1 root  wheel  23 Mar  8 19:56 /usr/local/groovy -> /usr/local/groovy-1.6.0
lrwxr-xr-x  1 root  wheel  25 Mar  8 19:56 /usr/local/grails -> /usr/local/grails-1.1-RC2
8 Comments

Using Groovy Regular Expressions to Parse Code From a Markdown File

2009/01/1

The January 2009 issue of GroovyMag was released today. In it, I’ve written an article that shows how easy regular expressions are to use in groovy. It starts with some regular expression basics, shows some common idiomatic groovy usage patterns and wraps up with some of the cool new features that groovy 1.6 is adding to regexp handling.

There are over 30 code samples in then article and I wanted to make sure while writing and editing that all of the code samples ran exactly as they appeared in the article text. Also, when you download an issue of GroovyMag, you get a zip file that has a PDF and a set of code “listing” files for each article. Each listing file contains a snippet of groovy code that appeared in the issue.

Directory screenshot showing listing files

I decided to write a couple of simple groovy scripts to keep things DRY, and to ensure that my edits didn’t break anything. The first script extracts code listings out of my draft article and saved them to individually numbered listing files. The second script executes each of the listing files and reported success or failure for each. Sort of a poor man’s JUnit for writing articles.

Read the rest of this article »

3 Comments

Getting Grails New Uber Generate-All to Proceed without Prompting

2008/12/9

In my current project, I’ve been doing a lot of tweaking of the default grails scaffolding templates. Because of this, I need to run the new uber generate-all command quite a bit to recreate things.

The one problem with this script is that if the files already exist, a prompt will come up after ~10 seconds or so (after the grails environment bootstraps) asking you if you want to Overwrite everything:

grails generate-all "*" 
...
~10 seconds pass
...
Generating views for domain class Baz ...
File /foobar/grails-app/views/baz/list.gsp already exists. Overwrite?y,n,a

This was a bit of a pain as I’d often kick the script off, get distracted and then come back to the shell with that prompt still waiting for me to tell it what to do. I’d rather just start working with my shiny new scaffolding.

The easy solution to this is simply to pipe the answer you want into the grails command:

echo "a" | grails generate-all "*"

Doing that will pipe the “a” into the grails command so that when the prompt finally comes up, it knows that it can continue regenerating all of my scaffolding.

It seems simple enough after I figured it out, but I thought it could save some other people time when they’re hacking around with templates and know they want to regenerate all of them.
Read the rest of this article »

2 Comments