A touchscreen mod for the Asus Eee 701
My Asus Eee PC has finally received some attention: I installed a touchscreen. The full story is after the jump ..
Continue Reading 2 comments May 15th, 2008 mikeb
My Asus Eee PC has finally received some attention: I installed a touchscreen. The full story is after the jump ..
Continue Reading 2 comments May 15th, 2008 mikeb
Last weekend I finally revisited the diff-in-javascript code I’d written a couple of years back, adding (very simple) patch-like and diff3-like functionality.
On the way, not only did I discover Khanna, Kunal and Pierce’s excellent paper “A Formal Investigation of Diff3“, but I found revctrl.org, the revision-control wiki, which I’m just starting to get my teeth into. I’m looking forward to learning more about merge algorithms.
The code I wrote last weekend is available: just download diff.js. The tools included:
Diff.diff_comm - works like a simple Unix comm(1)Diff.diff_patch - works like a simple Unix diff(1)Diff.patch - works like a (very) simple Unix patch(1) (it’s not a patch on Wall’s patch)Diff.diff3_merge - works like a couple of the variations on GNU’s diff3(1)Read on for some examples showing the library in action.
Continue Reading 2 comments May 9th, 2008 tonyg
Long, long ago, I complained about various warts and infelicities in E4X, the ECMAScript extensions for generating and pattern-matching XML documents. It turns out that two of my complaints were not well-founded: sequence-splicing is supported, and programmatic construction of tags is possible.
Firstly (and I’m amazed I didn’t realise this at the time, as I was using it elsewhere), it’s not a problem at all to splice in a sequence of items, in the manner of Scheme’s unquote-splicing; here’s a working solution to the problem I set myself:
function buildItems() {
return <>
<item>Hello</item>
<item>World!</item>
</>;
}
var doc = <mydocument>{buildItems()}</mydocument>;
You can even use real Arrays (which is what I tried and failed to do earlier), by guerilla-patching Array.prototype:
Array.prototype.toXMLList = function () {
var x = <container/>;
for (var i = 0; i < this.length; i++) {
x.appendChild(this[i]);
}
return x.children();
}
function buildItems() {
return [<item>Hello</item>,
<item>World!</item>].toXMLList();
}
var doc = <mydocument>{buildItems()}</mydocument>;
Programmatic construction of tags is done by use of the syntax for plain old unquote, in an unusual position: inside the tag’s angle-brackets:
var tagName = "p";
var doc = <{tagName}>test</{tagName}>;
So in summary, my original expectation that E4X should turn out to be very quasiquote-like wasn’t so far off the mark. It’s enough to get the basics done (ignoring for the minute the problems with namespace prefixes), but it’s still a bit of a bolt-on afterthought; it would have been nice to see it better integrated with the rest of the language.
2 comments May 7th, 2008 tonyg
I’ve updated our STOMP adapter for RabbitMQ to fix a bug reported by Carl Bourne. In the process, I updated the code to work with the latest snapshots of RabbitMQ, including the currently-released version, v1.3.0.
You can get the code by checking it out from our repository with
hg clone http://hg.opensource.lshift.net/rabbitmq-stomp/ hg update rabbitmq_v1_3_0_branch
or you can instead download a snapshot of the current state of the adapter[1], currently at revision 392d8cc8449c.
(Update: I forgot to mention that the mercurial repository has two branches in it: default, which tracks our internal RabbitMQ server repository, and rabbitmq_v1_3_0_branch, which should stay compatible with the 1.3.0 server release. Thanks to Aman Gupta, who pointed out the problem in a comment below!)
Here’s a summary of how to build and run a STOMP-enabled RabbitMQ broker - for more details, see the original post on the topic:
First, retrieve the RabbitMQ server 1.3.0 source code, and unpack it:curl http://www.rabbitmq.com/releases/source/rabbitmq-1.3.0.tar.gz | tar -zxvf -
Next, grab the latest STOMP adapter (here we download a copy of the rabbitmq_v1_3_0_branch rather than the main trunk):curl http://hg.opensource.lshift.net/rabbitmq-stomp/archive/rabbitmq_v1_3_0_branch.tar.gz | tar -zxvf -
Compile the server itself:make -C rabbitmq-1.3.0/erlang/rabbit
Finally, compile the adapter, and start the server with extra options that cause the adapter to start too:make -C rabbitmq-stomp-rabbitmq_v1_3_0_branch run
If this is successful, you should end up with “starting STOMP-listeners …done” and “broker running” in your terminal. At this point you can try out the service - for instance, you can run Carl’s test cases if you have ruby and rubygems handy:
sudo apt-get install ruby sudo apt-get install rubygems sudo gem install stomp ruby rabbitmq-stomp-rabbitmq_v1_3_0_branch/priv/tests-ruby/cb-receiver.rb
and in another window
ruby rabbitmq-stomp-rabbitmq_v1_3_0_branch/priv/tests-ruby/cb-sender.rb
It will transfer 10,000 short messages, and end up displaying
... Test Message number 9998 Test Message number 9999 All Done!
in the receiver-side terminal.
If you’re interested in the gory details of the bug-fix itself, you can see the relevant patch here. The problem was that the code that handled abrupt socket closure wasn’t handshaking with enough of the internals of the server to ensure that the last few work items were being processed successfully. Trapping socket closure in the STOMP adapter code, and politely handshaking, turned out to be all that was required. An alternative workaround would be to use STOMP’s DISCONNECT method before closing the socket on the client side.
Footnote 1: Note that despite the misleading URL, the snapshot download really is of the STOMP adapter, and not of the broker itself! I’m making use of hgwebdir’s archive-download feature here.
5 comments April 30th, 2008 tonyg
I’ve written before, to no acclamation, about the difficulty in factoring CSS. After more talking to and working with people who use CSS a lot more than I do (and are commensurately more skillful), I think the difficulty is the level of abstraction: CSS is declarative, but it is not very abstract.
Usually the idea with declarative languages is to describe the desired outcome and let the computer do the figuring out how. CSS only deals with mechanism. It does abstract from the how of layout and rendering; but, I would argue, not in a very useful way: I want to say “make sure this image lines up”, but what I can express is “nudge the image down by ten pixels”.
It is like navigating in a rocket ship by manually controlling the thrusters, when a computer is perfectly capable of working out the whole thing ahead of time. (Of course you may want to pilot the rocket ship manually for fun’s sake – Jef Raskin noted that lack of expressiveness was what made games fun and most other human-computer interfaces rubbish.)
However: CSS is what we have. What can we do to make it a better tool?
We can add the ability to express intent. The simplest example is with constants: if I could write
@let COLUMN_WIDTH: 200px;
#foo {
width: COLUMN_WIDTH;
}
#bar {
margin-left: COLUMN_WIDTH;
}
it makes it obvious that the margin and the width are deliberately the
same. It also means that a value only needs to be
given in one place – handy for colour schemes.
Once there are symbolic values, it follows to have
expressions in value position. This is useful for layouts that
involve margins and widths in some combination:
margin-left: COLUMN_ONE_WIDTH + COLUMN_TWO_WIDTH.
Another way to increase bang for syntactic buck is to add in the ability to abstract idiom: instead of
.box .c,
.box .t,
.box .b,
.box .b div {
background: transparent url(../img/extra-box-bg.gif) no-repeat top right;
}
#glass .box .c,
#glass .box .t,
#glass .box .b,
#glass .box .b div {
background: transparent url(../img/timeline-box-bg.png) no-repeat top right;
}
.side .box .c,
.side .box .t,
.side .box .b,
.side .box .b div {
background: transparent url(../img/side-box-bg.gif) no-repeat top right;
}
we could have
@def rounded(SELECTOR, BG) {
SELECTOR .c,
SELECTOR .t,
SELECTOR .b,
SELECTOR .b div {
background: transparent url(BG) no-repeat top right;
}
rounded(.box, ../img/extra-box-bg.gif);
rounded(#glass .box, ../img/timeline-box-bg.png);
rounded(.side .box, ../img/side-box-bg.gif);
Of course, it is easy enough to write a program to generate CSS using some general-purpose programming language, or even a templating language; but I think it will be more fruitful to grow the established language outwards. Doing so maintains hygeine – avoiding pitfalls of the “building SQL strings” kind, for example – and allows for analysis.
This is all wishfulware until someone makes it happen. Since I can’t much influence the specifications or browser implementations, I’m working on a compiler that targets plain-old CSS. Elsewhere, there is a proposal for adding constants to CSS, and a proposed mechanism for rule reuse.
5 comments April 30th, 2008 mikeb
(Continued from Moving away from CVS)
The wealth of options for a replacement for CVS presents us with a problem. We can’t choose a version control system by comparing feature lists: what seems perverse when presented in the manual may become natural in real use (which is the reaction many have to CVS’s “merge-don’t-lock” way of working at first), and contrarily what seems attractive on paper may prove problematic in real use (the system may claim sophisticated merging, but will it actually do what you want given your version history?). Equally, however, trying to use every system in anger would impose a very serious cost: unless we write the infrastructure for every system we test, some live project will have to do without it while they try out the shiny new system, and for every system someone will have to undergo the considerable expense of really learning how to use it and make it behave well. So we have to find ways to at least thin the candidate list.
Continue Reading 11 comments April 30th, 2008 Paul Crowley
When LShift first started off in 2000, the only real option for mature, open source version control was CVS. We’ve used CVS for most of our projects since then, and gone on to develop a strong infrastructure for managing CVS-backed projects, including a web interface for viewing versions, a web-based searchable database for related CVS commits (”CVSzilla”) which infers transactions from multiple simultaneous commits, and integration with the Bugzilla bug tracker.
Today, there are many other options, and I’ll discuss six major alternatives here: Subversion, Monotone, darcs, Git, Bazaar, and Mercurial.
Continue Reading 1 comment April 24th, 2008 Paul Crowley
In 2002 I was asked to add graphs to a financial website.
I started by considering off-the-shelf freeware Java packages, but a few hours of research suggested that none of them were quite customisable enough (as may well still be the case in 2008, perhaps astoundingly). So I decided to write my own graph package - the third or fourth I’ve done, I think.
There was an immediate problem, because my boss thought it was all taking too long (this after a week or two) with not enough visible progress. The perception, after I’d shown him a wiggly line generated on the first day by a freeware package (subsequently deemed inadequate) was “we’re going backwards”. It was clear that there was a potentially career-limiting loss of confidence here. Also, I was working off-site, and the company didn’t really have any way of monitoring me - adding to concerns that what I was doing might not be sensible.
The boss took to ringing me up more and more often to demand progress reports. Naturally, he would always do this just as I was in the middle of debugging the axis generator, or some other heads-down task, and so he’d get an unsatisfactory or distracted response… I was becoming a classic instance of a techie “going dark”, and crisis was imminent.
After one particularly painful meeting, I solved the problem by suggesting I send twice-daily email updates. This turned out to be a wonderful and rare example of coming up with a simple, effective management tool.
Typically, the emails would take 20 minutes to write and be 10 lines long, saying something like “I’ve done X, tried Y but it didn’t work because Z, am doing W next”. They didn’t generally require much feedback. The great thing was the discipline of having to report what I’d done every half-day. For all I know, the boss hardly ever read the reports, but this didn’t matter - by telling him what I was doing, I’d implicitly given him the opportunity to monitor it, in a non-intrusive way.
I’d describe what I was doing in the language of features, e.g. “shall I add a logarithmic scale option?”or “now I need to add a module to calculate and display dates properly in different time ranges” and the response was generally something like “yes, great idea”. Confidence was restored.
I’m still proud of that graph package, a worthy successor to the DOS/Windows/OS2 ones I’d done previously. It took two months, and the main thing I remember was that there were twelve off-the-peg graph sizes: Micro, Tiny, Miniature, Small, Pocket, Medium, Compact, Big, Large, Huge, Colossal and Gigantic. (Pocket started off as “Undersized”, but I decided that name wouldn’t do.) Micro was so small that it only made sense as a footnote to other web pages. As for Gigantic, it lived up to its name, and was a response to certain awkward users of the website who kept complaining that the graphs weren’t big enough. Later on, I refactored it so that you could have dynamically updating real-time graphs with all the same sizes and features, viewable in an applet.
As for the “management technique”, I suppose it was a bit like Scrum. For me the moral was that you have to keep management updated, proactively if possible. Also that it’s often reassuring to give people detail, even if they don’t want to drill down into it.
3 comments March 19th, 2008 felix
When you write unit tests, the minimal requirement before being able to try them out is that they compile. In Smalltalk, this means things like syntactic well-formedness, and perhaps the presence of global variables (i.e. classes) that you reference in the test method body.
It’s very quick and comfortable in Smalltalk to develop supported by unit testing: to write tests you know will fail, and refine away the failures until your test suite passes.
In Java, it’s much less comfortable, because besides the basic requirement of syntactic well-formedness, all the methods, classes, interfaces, and packages that your code relies on, directly or indirectly, must be present in the system before you can even try a run of the test suite! This makes for a less incremental style of development.
It would be very interesting to see a unit-testing framework for Java that simply treated a non-compiling test as a normal test failure, rather than a complete show-stopper, and which let you continue with the other tests in the suite. At the end of a run, it would include the non-compiling tests in the final reports just the same way as any other unexpectedly-failing test is reported.
4 comments February 22nd, 2008 tonyg
Barry Pederson’s excellent py-amqplib Python AMQP client comes with a very cute little demo, demonstrating how easy it is to do sophisticated cron-like things with AMQP and RabbitMQ.
As Barry writes in the example, the trick is to “[fire] off simple messages at one-minute intervals to a topic exchange named ‘clock’, with the topic of the message being the local time as ‘year.month.date.dow.hour.minute‘, for example: ‘2007.11.26.1.12.33′, where the dow (day of week) is 0 for Sunday, 1 for Monday, and so on (similar to Unix crontab). A consumer could then bind a queue to the routing key ‘#.0′ for example to get a message at the beginning of each hour.”
Lovely!
1 comment February 8th, 2008 tonyg
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Jun | ||||||
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 | |||