Squeak 4.2 has finally shipped!

It continues the improvements started in 4.0 and 4.1, with the trunk model revitalising the community: a small group of dedicated, frequentÂ committers provide the main thrust of development, supported by a veryÂ simple and lightweight way of providing bugfixes, enhancements, andÂ the like.

Squeak 4.2 also ships with the Cog VM, Eliot Miranda’s much speedierÂ virtual machine – most people report a 2x to 10x speed increase over the older VM.

Unfortunately for me, there’s a well-known issue with Squeak’s UUIDÂ plugin on 64-bit Linux machines, so if you’re running one of those, doÂ yourself a favour and delete the UUIDPlugin: rm coglinux/lib/squeak/3.9-7/UUIDPlugin.

I’ve submitted a number of bugfixes to Squeak 4.2, so this seems likeÂ a good point to reflect on how I fix bugs in Squeak.

Squeak has what’s called a trunk model: a small number of “blessed”Â committers apply bugfixes or enhancements to a central place, in theÂ form of a Monticello repository.

Anyone may submit bugfixes, enhancements, or whatever they like to theÂ Inbox, another Monticello repository. Commits are automaticallyÂ announced to squeak-dev (as are commits to Trunk). The mails allow theÂ community a handy feature-specific mail thread for comments,Â suggestions, and the like.

Squeak uses Monticello as its version control system. It needs lotsÂ more work before it’s as easy to use as git or Mercurial [1]. The mostÂ glaring missing feature is that I often want to commit some of myÂ work. I’m working on one thing, maybe see a bug that’s trivial to fix,Â and I want to put that fix (and the test that exposes the originalÂ bug!) in a separate commit. There is currently no simple way to doÂ that in Monticello. [2]

I don’t usually run into this problem when bugfixing trunk, but IÂ frequently run into this issue when working on my own packages.

Most of the time, the bug’s reproducible, and I can write a testÂ demonstrating the bug. Important, because then I know when I’ve fixedÂ the bug! The core packages (those loaded by default in a Squeak image)Â usually have their tests in separate packages: Network, andÂ Network-Test, for instance. That means that usually I submit two commits to the Inbox. (This is another thing I’d like to see inÂ Monticello: those commits belong together and, in git, they’d formÂ part of the same commit.)

Sometimes, it’s difficult to write a test for the bug, especially whenÂ it’s a user interface bug. In that case, I trigger the behaviour, andÂ work from inside the debugger. If the bug’s something like aÂ MessageNotUnderstood error – you tried to send an object a messageÂ that’s not in its protocol, or you have a nil reference, and you seeÂ “UndefinedObject>>messageNotUnderstood:” in the stack trace – then IÂ work from inside the debugger – trawl around, find out what’s wrong,Â try fix it. Other times, I might have to insert “self halt” -Â Smalltalk’s version of a breakpoint is naturally enough a messageÂ send. Either way, I’ll end up fixing the bug from within theÂ debugger. This is completely normal behaviour in Smalltalk by theÂ way – everything’s an object, everything’s live, and you can freelyÂ edit even the debugger itself from within the debugger. [3]

I also sanity-check myself: I take my clean image, and load myÂ changes. First, the changes must load cleanly. Second, they must passÂ their own tests. Lastly, they shouldn’t break any existing tests,Â which I check by running all loaded tests.

After that, it’s up to the community, and especially the hard-workingÂ committers, to review the fix and accept or reject it.

Happy hacking!

[1] Monticello’s otherwise pretty easy to use, and does most of whatÂ I need.

[2] But there could be: a new version’s made up of a collection ofÂ definitions. By default, saving a new version of a package collectsÂ all definitions in that package, but I don’t see why one couldn’t saveÂ a subset of those definitions, selectable through some kind of UI. Sounds like an interesting experiment to perform.

[3] Very, very carefully: if you make a mistake, you’re toast, becauseÂ of course triggering an error in the debugger opens up a debuggerÂ which triggers the error which …