Text

Java to Emfatic via grep and sed

I needed to quickly convert a directory of Java files into an Emfatic file today. As I was recently singing the praises of UNIX, I though I’d share a super-easy way to do this using a couple of UNIX power tools, grep and sed.

I wanted to produce the Emfatic code shown below:

class A extends B {}
abstract class B extends C {}

The first step was to use grep to print all of the public classes in the current directory. I used the -h flag so that filenames of matching files are not included in the output:

> grep -h "public class" *
public class A extends B {

Unfortunately, this doesn’t match class declarations of the form “public abstract class”, so I had to extend the regular expression:

> grep -h "public \(abstract \)\?class" *
public class A extends B {
public abstract class B extends C {

Clearly this regular expression won’t match all possible Java class declarations (what if the keywords were in a different order?), but it was sufficient for my purposes. However, the Emfatic declarations should not contain the public keyword, so I added a line-by-line substitution using sed:

> grep -h "public \(abstract \)\?class" * | sed "s/public //"
class A extends B {
abstract class B extends C {

Finally, the Emfatic declarations must be terminated with a closing bracket, so I added a further line-by-line substitution that adds a } after the end of the current line (matched using $:

> grep -h "public \(abstract \)\?class" * | sed "s/public //" | sed "s/$/\}/"
class A extends B {}
abstract class B extends C {}

And there we go. A few minutes in the terminal saved me quite a bit of time, and taught me a few new tricks with grep and sed.

Text

My Viva

Last week I sat a viva (defence) for my PhD thesis. Here are my experiences of the examination, in case they might be useful to future PhD students.

Submission

After I submitted my thesis, my PhD supervisors and the university began to make arrangements for the viva. My viva took place roughly 2 months after I submitted. My supervisors and examiners made all of the arrangements for the day of the viva, such as room bookings and organising travel.

Preparation

I wasn’t sure how best to prepare for the viva. I reread my thesis and highlighted key sentences so that I could quickly remember the crux of my arguments in the viva. The highlighted passages weren’t as useful as I’d anticipated (I barely referred to them in the viva) but this part of my preparation did give me a bit of extra confidence.

While rereading the thesis, I spotted a few issues: typos, missing references and other omissions. One of my supervisors suggested that I needn’t worry too much about this because my examiners were likely to overlook minor issues (which can be fixed with corrections) and also I was likely to read the thesis much more closely (as I was already familiar with the work and the story).

On reflection, rehearsing a short summary of the thesis research was probably the most useful preparation I did. Friends who had passed their viva had mentioned that my examiners would probably start with a question like “How would your thesis be summarised? What are the main contributions?”. Sure enough, this was the first question that I was asked and I was very glad to have already thought a little bit about how to answer.

Immediately before the viva, I went for a coffee with one of my supervisors and a friend, which was the perfect distraction. We talked about anything but the viva, and I felt very calm when my internal examiner arrived to whisk me away to the exam. I would definitely recommend nattering about something completely unrelated to the thesis before sitting the viva.

Examination

My viva lasted for roughly 2.5 hours; I think this is fairly typical from the few people who have told me about their viva. I was asked quite a range of questions, mostly about: the overall goals and outcomes of the research; the research method; the evaluation techniques and conclusions; and technical questions about the tools I’d built and processes that I’d suggested.

My examiners pushed me quite hard on a few issues. Specifically, these harder questions related to: the way in which tools I’d built compared with other similar tools; the validity/usefulness of a specific evaluation technique; and justification for the way in which I’d chosen a particular semantics for the transformation language that I had built.

Apart from the (entirely predictable) examination nerves, the whole experience wasn’t unpleasant. In particular, I felt that I could take plenty of time to think about a question and answer slowly (I didn’t feel rushed by my examiners), and that helped me to settle down.

A couple of times at the start of the viva, I started answering questions without referring to the relevant sections of the thesis, and I think this was the most obvious mistake I made. My external examiner asked “Where is this in the thesis?” once or twice, and from then I often started my answers by finding the relevant section, waiting for everyone to find that part of the thesis, and then pointing at figures or tables. If I was to sit the viva again, I definitely would have used this style of answer throughout.

The viva concluded with my internal examiner asking whether I felt that there was anything more that we needed to discuss. As the questions had touched most parts of the thesis, I didn’t feel that there was anything more. I left the room, and my examiners discussed the result.

Results

After a short wait (which felt like rather a long wait), I was given the results by my examiners. In my case, this was “minor corrections” and, for me at least, this will entail making some changes to the thesis which are signed off by the internal examiner. Then a final version of the thesis can be printed, bound and deposited.

Overall, I was very pleased (and relieved!) with the result, and I actually quite enjoyed the experience once I overcame the initial nerves. I hope that these notes might be useful. If you’re sitting your viva soon, good luck!

Text

JRebel for enhanced hot-swapping in Eclipse

I run a lot of Eclipse plugins from source in a developer workspace, and often use a runtime workspace for my day-to-day work. This allows me to develop and test plugins in a single Eclipse installation. However, whenever I want to make a change to a plugin that I’m using, I have to shutdown my runtime workspace, make the change in the developer workspace, and relaunch the runtime workspace. I do this many times a day, and the process can take 2-3 minutes on my machine.

JRebel is an Eclipse plugin that can automatically propagate changes from the developer workspace to runtime applications I’ve been using it with my developer workspace, and changes are almost immediately reflected in the runtime workspace. Unfortunately, JRebel isn’t free (licenses start at $59 USD for a year). However, you can get a free 30-day trial via the Eclipse marketplace:

Installing JRebel via the Eclipse marketplace

Once installed, JRebel adds a tab to support launch configuration types. Below, for example, I’ve enabled JRebel for my runtime workspace:

Configuring JRebel for a runtime Eclipse application

Viola! That’s all of the configuration that I needed.

I’ve not decided whether it’s quite worth the cost of a license ($59 USD per year), but so far I’m very impressed. I hope that similar functionality becomes part of Eclipse…

Text

Enhancing existing types in Objective-C

The types built into Objective-C and the Foundation Classes provide many useful methods, but I’ve found some functionality to be missing. NSString, for example, doesn’t provide methods that search for substrings, which is a task I often want to perform in iOS apps. Fortunately, it’s very easy to add extra methods to existing types in Objective-C.

For determining whether one string contains another, I might like to add the following two methods to NSString:

- (BOOL) containsString:(NSString *)aString;
- (BOOL) containsString:(NSString *)aString
           ignoringCase:(BOOL)flag;

I could subclass NSString, creating NSSearchableString which has the above methods, and use NSSearchableString throughout my program. However, whenever I wanted to search an NSString, I’d need to first convert it to an NSSearchableString.

Categories enable an alternative approach. When they were first introduced, categories were used to break the implementation of a class over several files. However, categories are also used to add methods to existing types. For the substring example, we can use a category to enhance NSString with the methods defined above:

#import <Foundation/Foundation.h>

@interface NSString (SearchingAdditions)
  - (BOOL) containsString:(NSString *)aString;
  - (BOOL) containsString:(NSString *)aString ignoringCase:(BOOL)flag;
@end

Notice that we’re defining methods for the NSString type, using a category called SearchingAdditions (specified in parentheses, after the type). Conventionally, this interface is stored in a file named NSString+SearchingAdditions.h

After providing an implementation for these methods, we can call them as we would any other method on NSString:

NSString *email = [display text];
if ([email containsString:@"."]) {
   // ...
}

In summary, categories provide a neat way of transparently adding methods to existing types in Objective-C. For the curious, an implementation of the containsString methods can be found here.

Text

Time Travelling with Git

Today, I was in the midst of changing some code when I discovered a bug. I wondered whether the current set of changes had introduced the bug or if it had been around longer than that. Fortunately, I’m using Git for this project, which has some really handy commands for time travelling…

First of all, I used stash to store away my current changes and revert to the last committed version of the code:

> git stash

I discovered that the bug was still present in the last commit; I must have introduced it in an earlier commit. To switch to earlier commits, I used:

> git checkout <commit_id>

Using git log to find the correct commit_id.

When I found the cause of the problem, I restored the latest version of the code:

> git checkout master

I fixed the problem in the latest version of the code, and committed.

Finally, I restored the changes I’d been working on originally, “unstashing” them:

> git stash pop

Best of all, Git automatically merged the changes and the bug fix.

Hasta la vista!

Photo Set

Some photos from the MoDELS 2010 conference in Oslo, Norway.

Text

Cucumber and Web Services in Rails 3

Today I wanted to write a cucumber feature to check that a RESTful resource could be created by posting XML to my app:

Scenario: Post an event
  When An event titled "First event" is posted via the API
  And  I go to the events page
  Then I should see "First event"

Defining the first step took quite a lot of work. I discovered, thanks to Patrick Ritchie’s answer on StackOverflow, that Cucumber step definitions can use ActionDispatch’s post method to post XML:

post("/controller/index", xml_result, {"Content-type" => "text/xml"})

But this didn’t work for me; the raw XML was passed to my controller as a String, and not a Hash. The logs indicated that the content type was not “application/xml” or “text/xml”, but “application/x-www-form-urlencoded.” After inspecting the implementation of ActionDispatch::Integration::RequestHelpers#post, I found that the content type should actually be specified like so:

post("/events", event.to_xml, {"CONTENT_TYPE" => "text/xml"})

Et viola! The feature passed. The complete step definition looks like this:

When /^An event titled "([^"]*)" is posted via the API$/ do |title|
  post_event Event.new(:title => title)
end

def post_event(event)
  response = post("/events", event.to_xml, {"CONTENT_TYPE" => "text/xml"})
  raise "Posting the event '#{event}' failed." unless response == 302
end
Text

Freezing time in Cucumber

Today I found that I needed to write some date-sensitive tests for a little Rails app I’m building. I’m using Cucumber to capture my features, and I wanted to say something like this:

Scenario: See yesterday's date on yesterday's tracker
  When I am on the tracker page for yesterday
  Then I should see "27 July 2010" 

Where “the tracker page for yesterday” maps to a path like: tracker?date=2010-07-28

Because today’s date is the 28th July 2010, this test will pass today, but never again after today. Clearly, a brittle test like the one above is no good.

I recalled reading about a similar problem in a Thoughbot blog post. Sure enough, in the comments Pat Maddox suggested a neat Cucumber step to solve this problem:

Given /^the date is "([^"]*)"$/ do |date_string|
  Timecop.freeze Chronic.parse("#{date_string} at noon")
end

The step uses Timecop to stub out Time.now and Chronic to parse a date string. (I tried using Date.parse rather than Chronic, but ran into timezone problems).

Update Jonas Nicklas, the author of Capybara, notes that, for Cucumber scenarios, Timecop.travel is preferred to Timecop.freeze. The latter breaks Capybara’s autowaiting feature, and causes it to hang when it can’t find something on the page. Therefore, the step definition should be written:

Given /^the date is "([^"]*)"$/ do |date_string|
  Timecop.travel Chronic.parse("#{date_string} at noon")
end

This step definition allowed me to rewrite the scenario as:

Scenario: See yesterday's date on yesterday's tracker
  Given the date is "28 July 2010"
  When I am on the tracker page for yesterday
  Then I should see "27 July 2010"

Et viola, no time bomb!

Update 2 As supaspoida highlighted in the comments, it’s also necessary to turn off Timecop after the scenario has been executed. This can be achieved with a Cucumber hook. Here’s the code I’m using in features/support/unfreeze_time.rb:

After do
  Timecop.return
end
Text

Installing RMagick on Ubuntu 9.04

I’m using Ubuntu 9.04 as my production environment, and I had some trouble installing the rmagick gem (via bundler). I received the following error message:

configure: error: Can't install RMagick.
  Can't find Magick-config in ...

I tried Googling the error and followed various instructions for installing imagemagick on Ubuntu, but none of them worked. In the end, I realised I hadn’t updated aptitude’s package list:

sudo aptitude update

After that, I could install the libraries required for RMagick with:

sudo aptitude install imagemagick libmagick9-dev

However, installing the RMagick gem led to another problem. The version of imagemagick installed by aptitude was too old for the RMagick gem. At this point, I decided to install imagemagick from source:

sudo aptitude remove imagemagick libmagick9-dev

mkdir ~/sources
cd ~/sources
wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz

The I followed the instructions from the RMagick FAQ. In short, I ran the following:

tar xvzf ImageMagick.tar.gz
cd ImageMagick*

./configure --disable-static --with-modules --without-perl \
 --without-magick-plus-plus --with-quantum-depth=8 \
 --with-gs-font-dir=/usr/share/fonts/type1/gsfonts

make
sudo make install

sudo reboot

Now, I could install the RMagick gem via Bundler.

Text

RVM for multiple rubies

Last week, Apple released a Snow Leopard update containing a version of Ruby that had a fairly major bug in BigDecimal. I wanted to patch my OS, but not break ruby.

RVM to the rescue! RVM allows several versions of Ruby to be installed on the same machine. I followed the installation instructions here, and installed ruby 1.8.7:

rvm install 1.8.7

I set this to be my default ruby:

rvm --default 1.8.7 

And checked my config with:

rvm list

After a bit of confusion, I discovered that a key to using RVM is to never install a gem as root, as described on the RVM page for rubygems. Bundler interoperates well with RVM, so I intend to use Bundler to install gems from now on.

I’m using RVM and Bundler on my production server too, running Ruby Enterprise Edition and Passenger as per the instructions from the RVM website. I did find that installing REE via RVM took almost 2 hours on my VPS though.