Peter Ledbrook

A search for meaning in software and life
RSS icon Email icon Home icon
  • A couple of notes about Groovy syntax

    Posted on January 13th, 2010 Peter 8 comments

    I’ve seen a fair bit of Groovy code and there are a couple of common syntax usages that I think could do with some clarification. First off is use of the def keyword.

    As we all know, if you want to declare a variable in Groovy with no or dynamic type, you use def. But there are some subtleties to this seemingly simple rule. If you are completely new to Groovy, then you might interpret that rule to mean that an untyped method signature would look like

    private def someMethod(def arg1, def arg2) {
        ...
    }
    

    Groovy does in fact accept the above, but it’s more verbose that it needs to be. Method arguments need no type:

    private def someMethod(arg1, arg2) {
        ...
    }
    

    and if the method has a scope (private, protected, etc), then you don’t need def for the return type:

    private someMethod(arg1, arg2) {
        ...
    }
    

    However, if there is no explicit scope, the return type is required:

    def someMethod(arg1, arg2) {
        ...
    }
    

    This behaviour extends to fields and local variables as well. You do not need def if a variable is declared with a scope, the static keyword, or final. So all the following are valid field declarations:

    private static final name
    protected age
    static count
    final id
    static final PATTERN
    

    I guess some people like to use def to keep the syntax consistent with the typed version, but it just adds clutter to my eyes.

    The second usage I want to look at concerns GStrings. Many a time I have seen code like this:

    println "${name}"
    

    where name is some variable. Notice that there is no other text in the string, it’s just a single variable in a GString. Why? I think there might be two reasons: habit and as a replacement for toString().

    Once you get used to using GStrings, they become a habit. I have even found myself doing the above, even when the variable in question is quite definitely a string already! That just causes confusion for anyone reading the code, so I typically get rid of the quotes and braces as soon as I notice. I recommend you do the same, particularly as it may be you reading the code 6 months down the line.

    As a replacement for toString(), the GString syntax has the benefit of brevity. Some words of caution though. First, you may not need it. Take a look at the previous example: println() automatically calls toString() on it’s argument, so there’s no need to do it yourself. Second, if the variable or argument is definitely going to be a string, then the GString syntax just obfuscates the code. Last, but definitely not least, you end up with a GString instance.

    Most of the time, GStrings and strings can be used interchangeably. In fact, Groovy goes out of it’s way to make sure this is the case, so you don’t have to worry about it. But if you ever do an instanceof check that compares a GString to a string, you’ll get false as a result. It’s not common, but it can happen. We’ve hit the problem a few times in the Grails code.

    Before I finish, a quick note on GStrings. Groovy automatically coerces (or converts) some types to others. One such coercion is from GString to String. However, this automatic coercion can only occur if Groovy knows that the target type is a string. For example, if a method argument or a variable is declared explicitly as String. When you use dynamic types, it’s up to you to handle GStrings and normal strings correctly.

    Now you know what’s possible, you can make an informed choice as to the style you use.

  • London GGUG in the new year

    Posted on December 14th, 2009 Peter 5 comments

    After a successful Groovy & Grails eXchange run by SkillsMatter last week, it seems that there is plenty of interest in keeping the London GGUG going on a regular basis. Several ideas were floated then, so I thought I’d bring them up here and elicit feedback:

    1. Two or three standard talks of 30-45mins each about any subject. Topics I would like to see covered include (in no particular order):
      • Gaelyk
      • Griffon
      • Real life Grails on Google App Engine
      • Real life Grails on Cloud Foundry
      • Grails deployment and data migration
      • GPars and/or static Groovy
      • Writing AST transformations
    2. 6 * 10-15min slots on any topic, first come, first served
    3. Plugin-fest – anyone can get up and present for 5-15 mins on their favourite plugins (no agenda)
    4. Crowd-programming on an app, plugin, Grails issues, or anything else

    If anyone has other ideas on session types or topics, then please let me know. I’m hoping that I can organise one with SkillsMatter sometime in mid- to late-January, so place your vote on what type of session you’d like! I’m currently thinking of a session with 5 or 6 10-15 min talks on what people are using Grails for, with plenty of time for questions.

    I hope to see you in the new year!

  • A rant about QWERTY

    Posted on December 14th, 2009 Peter 2 comments

    OK, so it seems that it’s no longer fashionable to knock the QWERTY keyboard layout (or QWERTZ in Germany, I gather). A couple of times I’ve moaned about the layout, people have said its got a worse reputation than it deserves. Well, maybe.

    I did have a quick look at Wikipedia to find out some information, and that directed me to a one page QWERTY history. If that page is accurate, then it may not have been designed to slow down typists, but the aim of reducing the number of jams in a typewriter at the end of the 19th century is hardly geared towards efficient typing on computer keyboards. It’s not like we have to worry about jams these days, although crumbs, coffee, and other such evils are a different matter.

    Anyway, it’s not really QWERTY per se that bugs me. Yes, I think the Dvorak layout puts less strain on my fingers’ tendons. But I can nonetheless type fairly fast on a QWERTY keyboard (it’s only taken 15 years of software development to get there!). No, my main gripe is with using QWERTY on touch screens.

    One of my most memorable experiences with this was when I was trying to buy a train ticket from a new electronic ticket machine. There were many design issues with this machine, but I want to focus on the touchscreen keyboard. This is presented to the customer when he or she needs to go anywhere not on the quick links screen. Unfortunately my parents live in a not-particularly-large village, hence I had to type in the name of the station. That’s when I suddenly realised I had no idea where the keys were on the QWERTY keyboard!

    This may seem strange at first glance, because I use a keyboard almost every day of my life (how sad is that?), but once you take into account the fact that I touch-type, things start to make sense. I don’t visually map the letters to the keyboard – my fingers in effect just take on a mind of their own. As soon as I was faced with the QWERTY layout and had to visually locate the letters, I struggled because it has no logic. I got to the stage where I was putting my hands on the screen as if I were typing!

    What about all those people that don’t have experience with QWERTY? I know that techies may find this hard to believe, but not everyone has a lot of experience with computers and their keyboards, whereas almost everyone knows the alphabet. So why not display the keys in alphabetical order? I really think that no one actually bothered to field test the on-screen keyboard layout and simply went with QWERTY because “everyone knows it”.

    Every on-screen keyboard layout I have seen goes with QWERTY, but I’m convinced this is completely wrong-headed for any situation that doesn’t involve touch-typing. In particular, any application that can’t handle fast typing (I’m looking at you, ticket machine) has no call to use QWERTY. Nor does any application that is used by people of all ages and backgrounds. Unfortunately, I can’t help but feel that this travesty will continue until even our grannies eventually learn where the QWERTY keys are.

  • London GGUG, 9th December

    Posted on November 27th, 2009 Peter 10 comments

    So it looks like we’ll be able to fit a GGUG into the Groovy & Grails Exchange at SkillsMatter in London. The question is, what to do for it? Here are the suggestions I have seen so far:

    1. Host a couple of talks that didn’t make it into the conference.
    2. A session like Google’s OpenJam in which people talk about their projects for 10-15 mins.
    3. Graeme and I talk about the internals of Grails and how to contribute.

    If you have any other ideas, or favour one of the options above, let me know in the comments.

    Thanks,

    Peter

  • Testing your Grails scripts

    Posted on October 6th, 2009 Peter 5 comments

    One of the things that has longed bugged me with Grails is how difficult it is to test scripts. In the past I have pretty much resorted to manually testing the corresponding commands and hoping that nothing bad happens. As we all know, this isn’t a very reliable approach. So, I finally caved in and knocked up a system for testing Grails scripts. I even integrated it into the normal Grails test framework!

    This feature is only available in the latest Grails snapshots, from build 441 onwards, so don’t bother trying this with 1.2-M3 or earlier. It will be available in 1.2-RC1 assuming that the feature isn’t pulled (an unlikely event). That’s all you need. No extra plugins or libraries are necessary. So without further ado, let’s create a new Grails script with a test.

    A test-driven script

    “Hello world” examples are all the rage, so who am I to buck the trend? In this instance, we’ll create a script that echoes “Hello world” to the console and also creates a file. Since I have my TDD hat on, the first step is to create a test case for the new script.

    All script tests go into the test/cli directory, so create the file test/cli/HelloWorldTests.groovy and open it in an editor. The first version looks like this:

    import grails.test.AbstractCliTestCase
    import org.apache.commons.codec.digest.DigestUtils
    
    /**
     * Test case for the "hello-world" Grails command.
     */
    class HelloWorldTests extends AbstractCliTestCase {
        void testDefault() {
            execute([ "hello-world" ])
    
            assertEquals 0, waitForProcess()
            verifyHeader()
    
            // Make sure that the script was found.
            assertFalse "HelloWorld script not found.", output.contains("Script not found:")
        }
    }
    

    Short and sweet. First off, we extend the AbstractCliTestCase class so that we can run our target script easily and reliably, while capturing its console output. Don’t leave home without it! Or at least don’t try to write a script test without it.

    The test itself, i.e. the body of the testDefault() method, demonstrates two of the most important methods provided by AbstractCliTestCase. The execute() method takes a list of command arguments, the first of which should be the name of the command you’re testing. Since our hello-world command doesn’t accept any arguments yet, we only pass the string “hello-world” to execute(). Once invoked, this method initiates a new Grails process to execute the given command.

    Once the separate Grails process has started, the execute() method returns. That means your test code is back in control before the Grails command has actually done anything. What we really need to do now is wait for the Grails command to finish. Enter waitForProcess(). This behaves very simply: it will wait for the command started by execute() to finish and then return the exit code of the process. Successful completion of a command typically results in an exit code of 0, so that’s what we test for in our assert.

    Now that the command has finished, we can check what the output of the command was. At this stage, we just want to check that the command was started successfully. The verifyHeader() method checks that the usual stuff printed by Grails when it starts appears in the command output. We then check that Grails didn’t print the message indicating that the command couldn’t be found. See how we check an output property? It’s provided by the abstract test case and contains the full output of the Grails command.

    Running the CLI tests

    So, with the test in place, let’s try running it:

    grails test-app --other
    This will run all tests in the “other” phase, which is the phase the CLI tests are part of. The result of this command should contain the following:

    -------------------------------------------------------
    Running 1 cli test...
    Running test HelloWorldTests...
                        warning...FAILED
    Tests Completed in 200ms ...
    -------------------------------------------------------
    Tests passed: 0
    Tests failed: 1
    -------------------------------------------------------
    

    A quick look at the corresponding test report will show that our assertion failed: the HelloWorld script couldn’t be found. That’s easily fixed. Create a new script, scripts/HelloWorld.groovy, and put the following in it:

    includeTargets << grailsScript("_GrailsSettings")
    
    target(default: "A simple hello world script.") {
    }
    

    When you run the tests again, you will find that our test case passes now. Whoohoo! Of course, it’s still not doing anything.

    Another cycle of TDD

    Let’s now augment our test case by checking that the command echoes the string “Hello world” to the console and that it also creates a “dummy.txt” file in the target directory:

    ...
        void testDefault() {
            def targetFile = new File("target", "dummy.txt")
            targetFile.delete()
    
            execute([ "hello-world" ])
    
            assertEquals 0, waitForProcess()
            verifyHeader()
    
            assertFalse "HelloWorld script not found.", output.contains("Script not found:")
            assertTrue "Hello world message is missing.", output.contains("[echo] Hello world!")
            assertTrue "dummy.txt doesn't exist", targetFile.exists()
        }
    ...
    

    Run the tests and you’ll find the test case is failing again, as expected. Adding the following to your new script should do the trick:

    target(default: "A simple hello world script.") {
        ant.echo("Hello world!")
        new File(grailsSettings.baseDir, "target/dummy.txt").createNewFile()
    }
    

    That’s it. The command is doing what was originally required of it and now you have a test case to ensure that it doesn’t break.

    User input

    You should be able to extrapolate what we’ve done here to lots of scripts, but there is still one class of script that we need to handle: those that accept user input. For example, many of the “create” scripts prompt the user for a name. Others check whether the user wants to overwrite existing files. Fortunately, AbstractCliTestCase can handle this.

    Let’s say we’re running the generate-views command for a given domain class and that the views already exist. The code to test this should start:

        void testGenerateViewsWithExistingViews() {
            execute([ "generate-views", "org.example.MyDomain" ])
            enterInput("n")
            enterInput("a")
    
            assertEquals 0, waitForProcess()
            verifyHeader()
    
            // Check that first view was not overwritten, but the others were.
            ...
        }
    

    As you can see, you can have as many calls to enterInput() as you want. But remember that you should only have as many as there are requests for input from the command. Typically, the generate-views command will request input four times, once for each view. But by entering “a” the second time, the remaining views are automatically overwritten without the user being asked.

    If you’re interested in a more full-featured example, my DTO Plugin has some CLI tests for its generate-dto command. Happy testing!