Geek

A first

I’m just writing this quick post to celebrate the fact that, today, for the first time in my life, after sitting at or being near computers for pretty much as long as I can remember being conscious, I have managed to successfully install a printer and use it to print a document without a defect, misaligned margin, glitch, blur, fault, smudge, error, discoloration, warning, beep, loose cable or irritating pop-up.

You wouldn’t believe that, but the feeling is quite underwhelming. It’s like waking up to the fact that you’re just yet another mediocre carbon-based organism spreading filth in a universe that doesn’t need any more of it. It doesn’t make you feel any special, but anyway, thanks Apple Bonjour: at least I’m now a filthy carbon-based organism capable of printing documents without having a nervous breakdown - just like everyone else.

Geek
General

Comments (2)

Permalink

Thoughts on my experiments with Io

After a fit of Smalltalk envy a while ago, I’ve been playing with the idea of having an instance of my VM being seemingly “always up” and adding more and more code to it in an iterative fashion as I went through developing a system.

On top of that, after looking at the Rails Migrations and other database refactoring tools, it occurred to me that I should be able to do something quite similar to what migrations do to databases in my own code: instead of trying to keep a very regular and smooth codebase, I’d keep track of the changes applied to an “empty” environment, each change providing some value and tests on its own. Also, I should be able to dump some of the VM’s contents back into a script that can be executed on a “clean” VM and the behaviour between both machines should be the same.

My current language of choice, the very small, elegant and simple Io, made it easy to test out the concept. As a prototype-based, extremely dynamic language, you can pretty much reopen anything you want and attach more behaviour to it at any point. So, here are the basic rules I chose to develop an application that looked for collocations in a body of text:

  • Every change script should live on a file of its own, sequentially numbered (like 012_add_foo.io), containing all the changes necessary to the system to implement a particular feature (or story).
  • Every change script should have a test for the new functionality in a separate file in the test/ directory. Preferably, new functionality should be driven by them.
  • The change scripts will be run in sequence by a loader. The loader may also execute unit tests in pair with the change scripts or after all change scripts are loaded, to verify later change scripts did not break any of the existing behaviour. After the loader runs, the system should be ready to use.
  • If the latest change script is causing the code to break, fix it, but scripts that have already been superseded by others shouldn’t be changed unless they stop development of new change script (with a syntax error, for instance). This makes more sense when change scripts are created by other tools instead of humans.

So far, it has worked quite well - I ended up with 25 change scripts, one patch to the runtime APIs (which got accepted, yay!), plus a pretty simplistic loader script:


Directory folderNamed(“src”) fileNames sort foreach(name,
	if(name != “main.io” and name endsWithSeq(“.io”),
		“Loading #{name}” interpolate println
		doFile("src/" .. name)
	)
)

Because of my unfamiliarity with Io, I ended up writing pretty brittle unit test suite and broke the “build” a lot (my colleagues would certainly point out here that I break the build a lot, even in other languages, too), and didn’t manage to integrate the test runs in the loader either.

Anyway, the whole point of this exercise was this: it’s possible to do some really cool, dynamic refactorings when developing software like this.

I’m about to write my little Refactoring object, which allows me to do things like:


Refactoring renameObject(Foo, Fubar)
Refactoring renameMethod(Foo, foo, fubar)

The renaming of objects and methods won’t happen instantly across the codebase, as you’d expect from IDEs like IntelliJ or Eclipse - instead, the method or object to be renamed gets replaced with a proxy to the new one and every time the proxy gets hit, the caller method gets its code dumped to a new change script, with the appropriate replacements.
This should give me 100% accurate refactorings with very little disturbance to my development flow (of course, I had to change the way my flow works, but I think that’s a good compromise).

Geek
General

Comments (1)

Permalink

New host, theme, couple of updates

I have just finished migrating all my stuff from a friend’s dedicated server to my own little space at Dreamhost. So far, the service has been flawless, but please let me know if there’s anything wrong. I haven’t quite found a theme I like, and might have to adjust this one a bit.

Meanwhile, I got my tiny little cards from moo.com. The quality of the prints is really, really good. Plus, it’s cheap and novel. As are the USBCell batteries I got in the mail on the same day. They might not have enough power to keep my digital camera up for too long, but having the charger built into the batteries themselves is just so convenient it makes it worth it.

Blogs
Geek
General
Site Updates

Comments (1)

Permalink

Java feature request: static reflection

I don’t know exactly where to post this to get the most attention from the JCP, so I just thought I would put it on my blog and ask the readers to kindly link it appropriately so it reaches the right pairs of eyes. Apologies if this post sounds more like a rant; in some respects, it is.

I’ll tell you what I really, really need from a future version of Java. This is where I’m coming from: I’m going to be using a language where I have to spoonfeed the compiler by declaring the types of my variables, parameters, methods, collections (with the addition of generics, even more than that), and sometimes I want to do some whacky dynamic programming with proxies, CGlib or just good old-fashioned wrestling with the bytecode in a pool of mud.

In those cases, I want to be able to isolate the dynamic whackiness as much as possible from the rest of my “sane” code. I want to make my code read as nicely as possible, given the constraints and inherent line-noise of the language I chose (or had to) to use, and last but not least, when I rename something, I want every single last one of the references to be changed automatically for me, and I don’t want to even consider the slight possibility of having to dig around some XML file or JMock test to finish renaming what the IDE couldn’t find.

I want extended static reflection capabilities: when I tell Spring that every URI that starts with /something needs to go to SomethingController.doSomething(String), I don’t want to give it a method name, I want to give it a reference to the actual method. Likewise, when using JMock I want to write something resembling:

mock.expects(once()).method(Foo.class.instanceMethods.bar(String.class));

instead of:

mock.expects(once()).method("bar").with(isA(String.class));

Even though the former takes a bit more typing, that call to doSomething(String) is something IDEs can work out from the AST without any fiddly string search-and-replace operation.

This feature does not change the syntax of the language (doSomething() would be a call to a method inside some instanceMethods field belonging to Class) and does not introduce any incompatibilities I can think of.

So, why not?

Geek
General

Comments (7)

Permalink

Don’t take tests seriously

At my current project, we have a good definition of what the real data in the system will look like, since the first few releases are basically migration with the addition of some new features.

But, a couple of weeks ago, something started happening to the test code: instead of creating a place like ‘France’ and a non-place word that goes with it, like ’skiing’ - which is something you’d be likely to see in the production database, people were choosing their test data based on wacky and unrelated concepts. Places like ‘plate’ and non-places like ‘cheese’ were popping up left ,right and centre. Converting an object from ‘cheese’ to ‘pizza’ seemed quite odd when said out loud, but made sense in the code, just as converting a legacy object to the new domain model, after some validation and filtering did. But it’s a much shorter and visual sentence.

What happens when you do such a thing? Your test code looks like something you’d never put in production. No production code would have variables like ‘cheese’, ‘bacon’ or ’sausages’. But test code can afford that, as long as it expresses the behaviour you’re trying to test clearly, and weird variable names or test data don’t detract from that.

Plus, the hilarity that ensues when you get your customer talking about the stories in half-breakfast, half-business terms is enough to bring the team morale up a bit.

Any experiences on that? I’d like to hear’em!

Geek
General
Work

Comments (0)

Permalink