→ 29 August 2010.
Tags:
ruby,
programming
I had cause to repurpose this immediate feedback formatter to work with the SpecDoc rspec formatter. So here’s a minimal version that just monkey-patches the SpecdocFormatter class to provide immediate feedback. As long as it’s included somewhere before rspec starts running, it should do its thing…
(view link)
…
Dealing with non-local control flow in deferred CoffeeScript
→ 06 July 2010.
Tags:
programming,
javascript
…a continuation (hah!) of defer: Taming asynchronous javascript with coffeescript.
In my last post, I outlined the ideas behind defer and its current state. One of the things I mentioned is that how to deal with return statements in asynchronous code is not yet decided. I'd like to explore a few of those ideas here. If you haven’t read the previous post, I suggest that you do.
…
defer: Taming asynchronous javascript with CoffeeScript
→ 04 July 2010.
Tags:
programming,
javascript
defer is something I've been working towards in various fashions for many months now. It’s a way of writing asynchronous javascript in a more straightforward and synchronous-looking way. My current approach has been to modify the CoffeeScript compiler to introduce a defer keyword. There is currently some debate on the issue (parts one and two have even more history) as to whether the functionality is necessary, useful or appropriate. Here, I hope to show the reasons behind the idea, why it does what it does, and how it helps programmers write more concise and readable code.
…
iPhone OS "multitasking"
→ 18 June 2010.
Tags:
iphone,
programming,
apple
So apparently iPhone OS 4 (or iOS, as it’s now awkwardly named), still has no way to sync data in the background. “Multitasking done right” indeed.
To be clear, that means that for every application that syncs data with the web, you must explicitly open it (and maybe tap some buttons) to initiate a sync. If you have a third-party mail client, an RSS reader, a todo list and instapaper, that’s quite a lot of tedium to go through every time you want to sync data. Heaven forbid you have more than a handful of apps that might need to talk to the internet without your explicit direction.
Get over your ego, Apple, and just copy android properly next time.
…
→ 17 June 2010.
Tags:
programming
As an addition to my last post, I'd like to point out a great resource for getting started with android programming in scala. This article gives you a nice template to go from, and a brief rundown of the sbt build tool you can use to build and deploy your scala-based android app. Good stuff!
(view link)
…
zero install is great
→ 13 June 2010.
Tags:
programming
Zero install is a marvellous system that I've known about for a little while, but only just started to use. It’s a package manager (like apt or yum), with two important differences:
- Packages are distributed and named by URL – there is no single repository, just the internet. This makes for potential trust issues, but it’s far better than (for example) launchpad PPAs, because…
- Packages are installed and run as regular users. No root access required.
It also has some additional perks:
- Cleanup is trivial – just clean out your zero-install cache.
- Making packages is pretty simple.
For its convenience, using zero-install puts some restraints on you:
- No triggers. You can’t run a script on install / uninstall, because there are no such events – merely “run”. That means your program has to be self-contained, and must deal with any first-run issues in the code itself. Probably not a bad idea though.
- No arbitrary placement of files. I've got a bunch of customisations that (for example) put things in
/etc/profile.d. You can’t do that sort of thing with zero-install, not even in the user’s home directory (e.g ~/.config). This means it’s not a great solution for configuration-based packages that coexist on the filesystem in well-known directories, so I certainly don’t see it replacing APT for that sort of stuff any time soon. But it’s certainly an excellent tool for delivering both programs and libraries.
I've put together my first 3 zero-install packages, and hopefully there will be more to come. You can find them here: http://gfxmonk.net/dist/0install/
Two of them are existing software, and the third is a tiny utility for working with zero-install itself. You can click on the xml files in that directory listing for an overview of what each package does.
…
Battling javascript contortion with lisp (of all things)
→ 28 February 2010.
Tags:
programming,
javascript,
lisp
I'm pleased to report that my crazy notions of replacing javascript metaprogramming with lisp metaprogramming appear to be headed steadily in the direction of success. It'd take a while to explain exactly what I'm up to (and the reasoning behind it), but essentially I'm trying to solve the same problem that async.js, narrative javascript and strands all try to solve: asynchronous callbacks are ugly, error-prone and downright confusing.
All of the above mentioned tools are unsatisfactory in various ways. Both narrative javascript and strands are complex enough that I uncovered serious bugs in both reasonably quickly. async.js is much more stable (and I actually have a working application with it), but still requires very careful programming and only works on mozilla browsers.
So I set forth with parenscript, which is essentially javascript dressed up as lisp. It doesn’t make for any prettier javascript, but it does make for one hell of a metaprogramming opportunity using lisp macros.
The aim is to convert straightforward, procedural-style code into the contortion required to appease asynchronous callbacks. I'm certainly not done yet, but I do have some compelling proof to show that it’s a plausible thing to do with lisp. Here’s a contrived example for, say, getting all items from whatever feed the supplied item-id belongs to. This involves getting the item to find the feed it belongs to, then returning all items contained within that feed. The “store” objects in this scenario refer to lawnchair stores, which do asynchronous local datastore lookups:
(asyncfun get-sibling-items (item-id)
(defer item (item-store.get id))
(console.log (+ "item belongs to feed: " item.feed-id))
(defer feed (feed-store.get item.feed-id))
(ret feed.all-items))
And here is the generated javascript:
function getSiblingItems(itemId, cb) {
itemStore.get (id, function (item) {
console.log('item belongs to feed: ' + item.feedId);
feedStore.get(item.feedId, function (feed) {
cb(feed.allItems);
});
});
};
This is just a simple example, but the lisp code still shows a remarkable reduction of both noise and contorted control-flow, and the generated code ought to work in all browsers. Worth pursuing, certainly.
…
Javascript Object Promotion
→ 19 February 2010.
Tags:
javascript,
programming
So it’s not something you should have to worry about (often), but I just spent an inordinate amount of time figuring out exactly why a particularly innocuous-looking piece of code was failing. It’s also yet another surprising part of the javascript language, and if you often deal with javascript then it’s in your best interests to keep track of such oddities (there are a lot of them!).
To illustrate, consider the following array intersection function:
var list1 = ["a", "b", "c"];
var list2 = ["a", "b", "d"];
function intersect(a,b) {
// find the intersection of two arrays
var intersection = [];
jQuery.each(a, function() {
if(b.indexOf(this) != -1) {
intersection.push(this);
}
}
return intersection;
}
You might expect calling intersect(list1, list2) to return ["a", "b"], since those are the common elements in the two sets. However, what you really get is [].
The problem is that I was a bit lazy, and used jQuery.each() to iterate over my collection (I hate the for x in y construct, and for loops are just so C). The each method calls your provided function on each member of the provided array, setting this in the context of each call to the current array element.
But it turns out that when you call a method on a primitive string object, the javascript (well, ECMAScript really) language specifies that this call takes place not on the string primitive type, but on the String object type (it’s kinda like a boxed value in Java). That is, fun.call("some string") actually ends up as if you had written fun.call(new String("some string")).
The String and string objects will compare equal when using the “==” operator – but since they are of different types, they will not compare as equal using the “===” operator. Evidently that is the type of equality that indexOf() uses, therefore none of the String objects will ever appear in the array of string primitives.
Normally, you will neither notice nor care. However, when extending the String class or calling a function with a primitive type as the subject, you should keep this conversion in mind. Note that the conversion does not apply to function arguments, only to the subject of a function application (i.e this).
I'm continually amazed by the high quality answers found on stackoverflow.com – I posted this question asking why the object promotion occurs (and if that is indeed what’s going on), and was rewarded with an explanation and a link to the precise part in the ECMAScript spec where the behaviour is detailed.
…
Making sense of async.js
→ 12 February 2010.
Tags:
javascript,
programming
async.js is a fascinating library for taming asynchronous javascript. It’s highly experimental, and as far as I know, it only works in firefox. But the idea is an important (and useful) one, so I think it’s definitely worth knowing about.
There are a few approaches to dealing with asynchronous javascript:
Compile [some language] to javascript
This is the approach taken by GWT, pyjamas, and many others. It’s usually extremely heavyweight, so it mainly makes sense for big apps.
Compile [almost-javascript] to javascript
Most notably this includes Narrative Javascript and its successor, Strands. This is a reasonable approach, but the lack of maturity / tool support makes debugging extremely hard. Also, I ran into a number of bugs in both these libraries. The thought of finding and fixing more of those bugs is not at all fun.
Write a javascript library
This is doable, but typically looks hideous, convoluted, and is usually quite burdensome to try and use.
Async.js is the most plausible attempt at #3 that I've seen. It uses a reasonably clever (but not unknown) trick to to turn Javascript 1.7’s generator functionality into an event-based coroutine system. Specifically, this allows for a program to “wait” for a callback, while not actually blocking the javascript interpreter (as a synchronous AJAX call would). Go read the async.js page to learn more, because the following isn’t going to make much sense if you don’t know roughly how to use async.js.
…
Javascript's fragile "this" statement
→ 05 January 2010.
Tags:
javascript,
programming
Javascript’s this statement must be the most fragile and confusing statement I've come across. Many languages
have the concept of “this”, but none mess with it to hard as javascript does. As I have recently discovered,
there are two fundamental issues with javascript’s this:
this does not get captured when storing an object member into a function object
- you can never actually be certain what
this will be
For object-oriented programming, these two facts are entirely terrifying. Let me illustrate each one:
1. this does not get captured when storing an object member into a function object
function Obj() {
this.method = function() {
return "method() called - I am " + this;
};
this.toString = function() {
return "[Obj instance]";
}
}
Now, consider the following scenarios:
var obj = new Obj();
obj.method();
// returns "method() called - I am [Obj instance]"
var obj_method = obj.method;
obj_method();
// returns "method() called - I am [object DOMWindow]"
What happened to this? I can find no explanation anywhere as to why it has been lost (and the window object
used in its place), but it is consistent. This may not seem like a big deal, but even aside from the
awkwardness, it’s completely non-obvious – and therefore a great candidate for sneaky bugs.
2. You can never actually be certain what this will be
Some see this as a feature, and it is in some cases. But the fact remains that the caller of any function can
set this to be any object they choose is cause for great suspicion on the part of any callback code.
What’s worse, as a library writer there are cases where it’s impossible to not mess with the value of this.
Other languages have the concept of a unsplat operator. Google it if you don’t know this term, but basically
it will turn a list of objects into an argument list. That is, func(1,2,3) is the same as func(*[1,2,3])
(where * is the un-splat operator). This is very important for higher-order / functional programming, where you might
write a proxy function that wraps a normal function call with some useful behaviour.
Anyways, javascript does have an unsplat operator. Kind of… The following code will work:
function call_other() {
var _arguments = Array.prototype.slice.call(arguments);
var func = _arguments[0];
var func_args = _arguments.slice(1);
// do whatever proxy stuff you need to do here
func.appy(null, func_args);
}
Except for that first parameter to the apply function. Whatever you pass in there is what this will be set
to in the context of the called function. With no discernible means of extracting what this would normally
be for the given function, it becomes impossible not to clobber the otherwise extremely-useful this
statement.
…
Zenity: for the user-friendly scripter
→ 06 December 2009.
Tags:
programming,
linux
I just discovered zenity, which is a
great tool for simple gtk+ interactions with a script.
It has the following types of interactions:
- calendar (date picker)
- file / directory selection
- error / info message
- list picker
- question (yes/no)
- progress dialog
- systray notification
- and more… ( see the man page )
The usage is brilliantly simple, and it’s very unixy despite being a GUI tool. I just wrote a pygtk+
app to do some photo importing stuff, but doing it with zenity would have been far simpler.
Well worth keeping in mind for your next user-friendly shell scripts (particularly for the more advanced progress,
calendar and list picker dialogs).
…
Bash trick: indicate whether a session is running under SSH
→ 27 November 2009.
Tags:
programming,
tip
It’s worrying how often I execute a command on the wrong machine because I don’t notice the hostname in my bash prompt. So I eventually figured out a way to make it more obvious. This is the relevant part of my ~/.bashrc:
# colours
RED=`tput setaf 1`
GREEN=`tput setaf 2`
YELLOW=`tput setaf 3`
BLUE=`tput setaf 4`
MAGENTA=`tput setaf 5`
CYAN=`tput setaf 6`
WHITE=`tput setaf 7`
LIGHT=`tput setaf 9`
GREY=`tput setaf 0`
# make remote sessions stand out
HOSTNAME_COLOR="$YELLOW"
[ "$SSH_CLIENT" ] && HOSTNAME_COLOR="$RED"
# string it all together:
PS1='\[$GREEN\]\u\[$HOSTNAME_COLOR\]@\h \[$CYAN\]\w\[$GREEN\] \$\[$LIGHT\] '
The colours stuff is pretty standard, the crucial part is [ “$SSH_CLIENT” ] && HOSTNAME_COLOR=“$RED”. You can do anything in here to make a remote session stand out.
…
Is there such thing as a Snapping Window Manager?
→ 24 October 2009.
Tags:
linux,
programming
..in which I propose a potentially-new window management feature, and hope that somebody has already done it so that I won’t have to…
…
Google camera adapter (MagicCam) - osascript errors
→ 21 September 2009.
Tags:
mac,
programming
Just thought I'd shed some light on the issue (because googling it myself turned up less than useful results). I just had an issue where the following messages were being spewed into the output of every osascript (applescript) command:
$ osascript -e 'tell application "finder" to activate'
[000:035] MagicCam 0: Current process: osascript, Flash is loaded: no
[000:035] Error(magiccammac.cc:276): MagicCam 0: MagicCamOpen: Not an allowed process!
[000:002] MagicCam 0: Current process: osascript, Flash is loaded: no
[000:002] Error(magiccammac.cc:276): MagicCam 0: MagicCamOpen: Not an allowed process!
[000:000] MagicCam 1: Current process: osascript, Flash is loaded: no
[000:000] Error(magiccammac.cc:276): MagicCam 1: MagicCamOpen: Not an allowed process!
[000:002] MagicCam 1: Current process: osascript, Flash is loaded: no
[000:002] Error(magiccammac.cc:276): MagicCam 1: MagicCamOpen: Not an allowed process!
This has the potential to break a lot of scripts that use osascript to get information from (or about) running applications.
It turns out this is due to a google quicktime component, which I believe is related to google gears and video chat. To get rid of the error, you
can delete “Google Camera Adapter 0.component” and “Google Camera Adapter 1.component” from /Library/Quicktime/. I make no claims that google
video chat will work after you do this (it surely won’t), but I never use it anyways, and I'd rather not have it break anything that relies on
osascript output.
…
navim update
→ 12 September 2009.
Tags:
javascript,
programming
So I've kept working on navim, my jQuery plugin for easily adding vim-style keyboard navigation to web pages. New features include:
- shift+enter to open links in a new window (and the ability to tell if shift is pressed from a custom action callback)
- fixed a bug that interfered with pressing return to submit a form
- using focus(), blur() and tab-key navigation to better effect
I've also now implemented navim in my “read later” webapp, pagefeed. It was trivial enough to add “d” as an additional keyboard shortcut to delete the currently active item, which serves as a good example for anyone wanting to add their own custom action keys. The code is simply:
$(window).keypress(function(e) {
if(e.which == 100) { // 'd'
$(".navim_active").children("form.del").eq(0).submit();
return false;
}
});
…
The rise of vi keybindings on the web
→ 05 September 2009.
Tags:
web,
programming,
javascript
Vi? On the internet? No, not that one. I just mean vi keybindings, not the rest of vi. And I've just written a jQuery plugin to help make this happen.
On the UNIX terminal, many commands use common keyboard shortcuts to navigate screenfuls of text. j/k for down/up, h/l for left/right, and so on. As far as I know, vi was the first program to use these shortcuts. vi is famous for its modal interface, where different keys mean different things depending on what mode you’re in. In text insertion mode, “hjkl” means exactly those letters. But in normal (or visual) mode, they are the keys you use for navigation. Using standard letters instead of the arrow keys could have come about for a number of reasons. Firstly, there’s the issue that different terminals send different key-codes for special keys like the arrow keys. That’s generally been solved these days, but the other reason still remains: By using the whole alphabet as control keys, you get a startling amount of “command bandwidth” – that is, commands in vi generally require much less finger-contortion than pretty much every other text editor.
vi keybindings are useful on the internet for a third (but related) reason – keybinding collisions. We already have meanings for what the arrow keys do (scroll), and trying to use control-key combinations for webpage-specific functionality is fraught with user frustration, confusion and technical issues.
I've noticed it already with a bunch of google products, especially since I started using gmail’s online version most of the time now (instead of Mail.app). Gmail and Google reader are the two big ones that I use, but I'm sure there are more. Both use vi-style keyboard navigation, and both are a delight to use with the keyboard. I'd be surprised if bespin lasts long before a vi-mode is added.
I guess many people think only data-heavy, webapps are worth learning keyboard shortcuts for. But the real benefit comes when everything (or at least most things you care about) use the same convenient shortcuts. I was absolutely delighted when I noticed that every issue of The Big Picture allows you to use j/k to jump to successive images – incredibly useful in this case, because page up/down rarely manages to line up to image boundaries. It’s an unobtrusive addition, and it won’t hurt regular users. But for those who do use it, it quickly becomes indispensable.
So what I'd love is for all websites with many conceptual “items” on a page to implement the j/k keybinding as a minimum (with horizontal and inter-page navigation coming later, hopefully). To this end, I have written a jQuery plugin that should make the process fairly trivial, and allow for “active item” decoration via CSS. Click that link for a demo you can try out yourself.
If there’s enough interest, maybe someone could turn it into a community-based firefox extension (a-la AutoPager) that allows users to define the navigation items for websites that haven’t supplied their own (google search would be a handy one).
It’s worth mentioning Vimperator, which brings vi keybindings to firefox’s UI. To clarify, I'm not talking about browser functionality. I'm happy to use the existing controls for a browser, and leave the alphabet keys for use by the web-page. That way there’s no overlap, and webpages can provide contextual navigation controls that are much more powerful than the basic “scroll down 30 pixels” that a browser provides.
…
Recursively Default Dictionaries
→ 01 September 2009.
Tags:
programming,
ruby,
python
Today I was asked if I knew how to make a recursively default dictionary (although not in so many words). What that means is that it’s a dictionary (or hash) which is defaulted to an empty version of itself for every item access. That way, you can throw data into a multi-dimensional dictionary without regard for whether keys already exist, like so:
h["a"]["b"]["c"] = 5
Without having to first initialise h[“a”] and h[“a”][“b”].
A dictionary with a default value of an empty hash sprang to mind, but after trying it out I realised that this only works for one level. Recursion was evidently required.
So, here’s the python solution:
from collections import defaultdict
new_dict = lambda: defaultdict(new_dict)
h = defaultdict(new_dict)
And the ruby, which seems overly noisy:
new_hash = lambda { |hash, key| hash[key] = Hash.new &new_hash }
h = Hash.new(&new_hash)
…
→ 29 August 2009.
Tags:
programming,
git
I had to refer to this today, when I discovered (much to my surprise) that git submodules update does, for the most part, nothing.
You might expect it to update all my git submodules to the latest revision. Nope, I'm supposed to cd into each of those directories myself and run git pull myself.
The only hint that git update will do nothing of use is a single sentence in the help page, which mentions as part of the update command’s summary: “This will make the submodules HEAD be detached”. Which is a fairly unintelligible statement, even to someone who’s been using git for about a year now.
I can’t imagine when you would run git submodule update after the initial checkout – why doesn’t git submodule init just do update’s job (actually fetching the initial content), and then maybe we could have an update that actually pulls updates? I'd even be satisfied to have to use a flag, like --hard, --please or --come-on-old-chap-just-do-it-would-you
I'm pretty new to git’s submodules, and so far they just seem to take far too many manual steps (I don’t understand why they’re not fetched by a clone, for starters). I feel wrong saying so, but I miss svn:externals.
Tell me, how are things in the land of the other DVCS’s?
Update: Looks like my git is outdated, the newest version (1.6) allows a --merge or --rebase flag to update which sounds like it does what I want. Now I just need to sort out my mac’s package management :s
(view link)
…
OSX-style horizontal mouse scrolling for linux
→ 24 July 2009.
Tags:
programming,
osx,
linux
OSX has this great feature where if you hold down SHIFT at the same time as
using your mouse scroll wheel, it’ll scroll horizontally instead of vertically. If you
don’t have a laptop, this is an immensely useful trick. Sadly, I couldn’t find
any way to get this to happen on linux.
But now, thanks to some direction from stackoverflow,
I finally figured out how to do it myself.
The world of X11 input hackery is somewhat twisted and full of projects
either abandoned or in disrepair, but I finally stumbled across the right set of tools.
If you'd like to get this (rather excellent) feature in linux, you will need the following:
Install the packages xbindkeys and xautomation: sudo apt-get install xbindkeys xautomation
Save the following file as ~/.xbindkeysrc.scm :
; bind shift + vertical scroll to horizontal scroll events
(xbindkey '(shift "b:4") "xte 'mouseclick 6'")
(xbindkey '(shift "b:5") "xte 'mouseclick 7'")
Use your favourite mechanism to ensure that the xbindkeys command is run at the
beginning of your xsession (I added it to ubuntu’s “startup items” preference, but
you can surely use init.d if you’re comfortable with that).
…
Autonose: continuous test runner for python's nosetests
→ 21 June 2009.
Tags:
programming,
python,
application
Today I've put up the first “releaseable” version of autonose. Basically, it analyses your code’s imports, and determines exactly which tests rely on which code. So whenever you change a file, it’ll automatically run the tests that depend on the changed file (be it directly or transitively). Give it a go, and please let me know your feedback.
All you need do is:
$ easy_install autonose
$ cd [project_with_some_tests_in_it]
$ autonose
See the github project page for further information (and a screenshot).
…
minor metaprogramming
→ 12 June 2009.
Tags:
programming,
ruby
Can anyone tell me why ruby’s instance_variable_set would possibly require the name of a variable to start with an “@”, rather than simply assuming it? It’s a ruddy instance variable, after all…
I can find no decent alternative to python’s setattr in ruby, which surprises me.
…
The joys of functional programming with side-effects
→ 01 June 2009.
Tags:
programming,
python,
ruby
Quick quiz: what will the following pieces of ostensibly identical python and ruby programs print out?

If you answered “1 2 3 4” or something similar, you’re half right. That’s what you’ll get from ruby.
Surprisingly, python will give you “4 4 4 4”. I'm not the first
to discover this, but that doesn’t make it
any less startling.
The “fix” in python is to replace the lambda line with q.append(lambda i=i: puts(i)), because default
function paramaters are evaluated at definition-time, not evaluation-time (another difference from ruby, potentially
even related?). It makes sense once it’s explained what’s going on, but it’s hardly obvious.
I don’t know enough about how closures are done to say that python is wrong, but it’s certainly less desirable and more surprising…
(for those keeping score, this makes ruby: 1, python: still heaps ;P)
P.S. I couldn’t resist mentioning the title of a proposed solution to this problem: For-loop variable scope: simultaneous possession and ingestion of cake
update: As matt just pointed out, the ruby port is different in that it uses i as an argument to a block. A more faithful translation would be:
for i in (0..9)
q << (lambda {puts i})
end
Which has exactly the same outcome as python.
So there you go. It turns out closures are confusing. Who knew? ;P
…
Javascript: smells like lisp
→ 28 May 2009.
Tags:
programming
I was just struck by how lisp-ish javascript is getting (not in the powerful code-as-data way, just the “screw builtin language features, lets just use more brackets for everything” way). Exemplified by this tiny sammy example code:
$.sammy(function() { with(this) {
get('#/', function() { with(this) {
$('#main').text('Welcome!');
}});
}});
…
Entirely too much investigation into ruby's match operator
→ 02 May 2009.
Tags:
ruby,
programming
(how could a title like that not excite you! ;P)
So yesterday I had this weird regex issue in ruby. I wanted to get a regular expression containing a given string, but didn’t want to have to manually escape all the special characters. Regexp.escape to the rescue! It escapes all regex metacharacters in any given string, and returns it as a regex. In fact, the docs assure me:
For any string, Regexp.escape(str)=~str will be true.
But not so much in practice?
>> str = "123"
=> "123"
>> Regexp.escape(str)=~str
TypeError: type mismatch: String given
So, problem one: Regexp.escape is broken. It returns not a Regexp, but a string. Oddly enough it also seems to escape spaces and other innocuous characters, but at least you get the right result if you pump it through Regexp.compile(). However, that wasn’t my only discovery.
I mentioned this to Matt, and he couldn’t make much sense of it either. He noticed that the type error is specific to strings – if you use a number it just returns false:
>> 123 =~ 'foo'
=> false
Seems a bit odd, really. Fixnum doesn’t implement =~, nor does Integer.
So I went doc spelunking. I found implementations for =~ in the following three important classes:
Regexp: regexp =~ str: do a regex match, as you might expect
String: str =~ obj: Call obj =~ str (i.e swap the order of your operands). Not mentioned in the docs but clearly apparent in the source (and experimentation): raise a TypeError if both arguments are strings. Without this, matching one string to another would very quickly run out of stack space.
Object: obj =~ other_obj: return false
So the Regexp implementation is fine. The String implementation is a little odd. I guess it’s there to allow people to write matching statements either way, but it seems like a dangerous (and confusing) habit to condone.
But the Object implementation? Why??? What possible reason could one have for doing a match operation against two objects, neither of which implement any matching behaviour? This has the painful side effect of giving every single object I inspect a “=~” method which does nothing. No wonder Object.new() has over 120 methods on it *.
For comparison, python’s object only has 12 methods / attributes. And they’re all special names, so there’s no pollution of regular names going on.
So there you go, two spoonfuls of broken in the one discovery!
(this is ruby 1.8.6, if that matters)
* I exaggerate, over 120 methods on object are just what you get in a rails app. Vanilla ruby only has 41 by my count. but it’s still completely unnecessary, and adds noise to inflate that number
…
→ 28 April 2009.
Tags:
ruby,
programming
Pretty cool, I worry that such things can’t easily be done so cleanly in python…
(view link)
…
rednose: coloured output formatting plugin for nosetests
→ 29 March 2009.
Tags:
programming,
python
I recently wrote a plugin for nosetests which greatly (imho) improves the output for failed and errored tests. The screenshot explains it best.
To install, just run easy_install rednose. Then you can run nosetests with the —rednose option.
See github.com/gfxmonk/rednose for code and more information.
…
ruby - longing for some discipline
→ 21 March 2009.
Tags:
python,
ruby,
programming
More and more, I am wishing that there was some sort of strict mode I could enable in ruby to say “you know what? I'm careful with my code. Please don’t assume things behind my back”. And to be honest, this mode would pretty much be synonymous with “just do what python would do”
By default, python is strict. If you index a dict (hash) with a nonexistant key, you get a keyError. If you don’t want to have to deal with that, you can use the get method and provide a default for if the key doesn’t exist. In ruby, if you want to be strict about anything, you generally have to write your own checks to guard against the core library’s forgivingness. Forgivingness sounds nice at first, but goes completely against the idea of failing fast, and frequently delays the manifestation of bugs, making them that much harder to actually track down.
Two examples that I came across within minutes of each other the other day:
Struct.new(:a,:b,:c).new('a','b')
that should NOT go without an exception
"a|b||c".split("|")
=> ["a", "b", "", "c"]
good…. so now:
"a|b||".split("|")
=> ["a", "b"]
argh! what have you done to my third field?
…
Size matters
→ 06 March 2009.
Tags:
programming
On the same codebase, with no changes pending in either system:
$ time git status
# ...
real 0m0.618s
$ time bzr status
# ...
real 0m3.795s
It’s a small thing, but it matters.
…
Pretty Decorators
→ 20 February 2009.
Tags:
programming,
python
Python decorators are cool, but they can become very messy if you sart taking arguments:
def decorate_with_args(arg):
def the_decorator(func):
def run_it():
func(arg)
return run_it
return the_decorator
@decorate_with_args('some string')
def messy(s):
print s
ugh. Three levels of function definitions for a single decorator. And heaven forbid you want the decorator to be useable without supplying any arguments (not even empty brackets).
So then, I present a much cleaner decorator helper class:
class ParamDecorator(object):
def __init__(self, decorator_function):
self.func = decorator_function
def __call__(self, *args, **kwargs):
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
# we're being called without paramaters
# (just the decorated function)
return self.func(args[0])
return self.decorate_with(args, kwargs)
def decorate_with(self, args, kwargs):
def decorator(callable_):
return self.func(callable_, *args, **kwargs)
return decorator
All that’s required of you is to take the decorated function as your first argument, and then any additional (optional) arguments. For example, here’s how you might implement a “pending” and “trace” decorator:
@ParamDecorator
def pending(decorated, reason='no reason given'):
def run(*args, **kwargs):
print "function '%s' is pending (%s)" % (decorated.__name__, reason)
return run
@ParamDecorator
def trace(decorated, label=None):
if label is None:
label = decorated.__name__
else:
label = "%s (%s)" % (decorated.__name__, label)
def run(*args, **kwargs):
print "%s: started (args=%s, kwargs=%s)" % (label, args, kwargs)
ret = decorated(*args, **kwargs)
print "%s: returning: %s" % (label, ret)
return ret
return run
Which can then be used as either standard or paramaterised decorators:
@pending
def a():
pass
@pending("I haven't done it yet!")
def b():
pass
@trace
def foo():
return "blah"
@trace("important function")
def bar():
return "blech!"
And just to show what this all amounts to:
if __name__ == '__main__':
a()
b()
foo()
bar()
reveals the following output:
function 'a' is pending (no reason given)
function 'b' is pending (I haven't done it yet!)
foo: started (args=(), kwargs={})
foo: returning: blah
bar (important function): started (args=(), kwargs={})
bar (important function): returning: blech!
Fairly simple stuff, but hopefully useful for anyone who finds themselves tripped up by decorators – particularly when trying to allow for both naked and paramaterised decorators.
P.S: I've made a pastie of the code in this post, because my weblog engine is not cool enough to colour-code python ;)
…
Too magic?
→ 16 February 2009.
Tags:
programming
A snippet from the source code of my iPhone app, GRiS:
- (void) tableView: (UITableView*) tableView
willBeginEditingRowAtIndexPath: (NSIndexPath *) indexPath {
// the mere presence of this method causes a swipe action to be
// recognised, and a delete button appears. like magic!
}
I'm glad it was so easy, but fairly unnerved at the same time…
…
Remap shift+space to underscore
→ 29 January 2009.
Tags:
linux,
programming
So I had this great idea yesterday (for coders, at least): remap [shift+space] to [underscore]. Turns out I am far from the first to think of this, which only enforces its awesomeness as an idea.
Mac:
Put this in ~/Library/KeyBindings/DefaultKeyBinding.dict:
{
/* turn shift + space into underscore */
"$ " = ("insertText:", "_");
}
Linux:
for a PC keyboard, try:
xmodmap -e 'keycode 65 = space underscore'
or on a mac keyboard:
xmodmap -e 'keycode 57 = space underscore'
Or if neither of those work, run:
xmodmap -pk | grep space | awk '{print $1}'
and use that number instead of 65 or 57 above.
You can put this keybinding in ~/.xmodmaprc or somesuch if you like it.
…
Ruby class methods
→ 21 January 2009.
Tags:
programming,
ruby
Not a very exciting realisation, but an annoying one:
$ irb
>> class A
>> def self.meth; puts "class method!"; end
>> end
>> A.meth()
class method!
>> A.new().meth()
NoMethodError: undefined method `meth' for #<A:0x5ad160>
from (irb):11
ick…
(sadly enough, most of my posts tagged “ruby” would be equally well tagged as “things that suck in ruby”)
…
Package managers
→ 05 January 2009.
Tags:
programming
I can feel things getting ugly…
Recently I've been dealing with package managers, and debating which one to use. In different projects I'm currently using .deb packages (for cydia) and python .eggs (for the cheese shop / pypi / easy_install).
I'm a big fan of pypi / simple_install for python modules, but it obviously doesn’t make sense for general software. On the other hand, .deb repositories are a big world, and I don’t want to have to release all my python eggs in that global namespace.
But now I am writing a tool which relies on both python packages and installed command-line software. How on earth do you specify dependencies across packaging worlds? Should we release all packages on all packaging systems in order that any future package can depend on the appropriate version of your package in its chosen package distribution format? ugh…
And then we just get into these meta-packagers like easy-deb
What’s the answer? Perhaps if there was some way to delegate dependencies? So for example my .deb package could depend on easy_install and pypi:somelib. Then there would only need to be a single “pypi” package which could ensure the pypi-world dependencies for somelib were satisfied and somelib is installed.
(I don’t know how that would go for uninstalls though. Especially considering that simple_install can’t even do uninstalls…)
Excuse the rant, and please point out if something does in fact exist to ease the headache…
…
→ 29 December 2008.
Tags:
programming
This is the plugin version of a script I made a while ago to set the opacity of each feed in google reader’s feed list according to how many unread items are in it.

(view link)
…
→ 26 December 2008.
Tags:
programming
new and shiny!
(and almost entirely incompatible with the previous version :s)
(view link)
…
→ 06 December 2008.
Tags:
python,
programming
I've been working on this a little while now. At work, I use ruby. It has its good points, but my language of choice is still python. I am, however, blown away by rspec. So I've tried to bring some of its features into python (namely and should_receive matchers).
Thus was born mocktest. The readme has all the examples you should need to start using it in your own testing code.
It’s also available from the cheese shop, which means you can just run easy_install mocktest to install it on your system.
I should note that this code builds upon the excellent Mock library by Michael Foord.
(view link)
…
Ruby is friggin weird. And a little messed up.
→ 21 June 2008.
Tags:
programming,
ruby
(if you don’t read my blog for the geeky thrill of it, you may want to give this post a miss ;))
Follow my little IRB session, if you will:
>> nil or "val"
=> "val"
>> puts (nil or "val").inspect
=> "val"
>> x = nil || "val"
=> "val"
>> x
=> "val"
>> y = nil or "val"
=> "val"
(wait for it…)
>> y
=> nil
Seriously, ruby. What the crap?
Okay, so I just figured out what’s going on here. “or” works both as a logic operator and a conditional statement. Just like you can do:
x = something_dangerous() rescue "x failed!"
and
puts "x is greater than 10" if x > 10
It would seem you can also do
x = some_value or puts "i guess the assignment didn't evaluate to true"
Meaning that in my example above:
y = nil or "val"
Ruby evaluates it as:
(y = nil) or ("val")
(i.e. in the second set of brackets, y is not actually assigned to anything)
When I found out that the symbol-based ones bind tighter than the keywords, I winced a little and noted to myself never to rely on that, because it’s neither readable or obvious.
Now that I've stumbled upon this latest gem of knowledge, It just makes me cringe…
…
@ruby: You're Doing it Wrong.
→ 13 June 2008.
Tags:
programming,
ruby
Pay attention to the output types, kids:
>> { "key" => "val" }.reject { false }
=> {"key" => "val"}
looking good so far...
>> { "key" => "val" }.select { true }
=> [["key", "val"]]
eww... what?
…
HTML to PDF converter
→ 05 May 2008.
Tags:
application,
python,
mac,
programming
Given the integration of PDF into Mac OS X, I was surprised to find that there didn’t seem to be any tool to convert HTML files into PDFs. So, like any frustrated coder I wrote my own little script to do it: html2pdf.py
Requires python and OSX 10.5 (Leopard). It uses a WebKit view for the rendering, so in theory it should work with any URL that safari can handle – but I haven’t exactly tested it thoroughly…
…
Trashy.app
→ 20 April 2008.
Tags:
application,
programming,
osx
In any OSX “document window”, there is a little icon representing the current document. If you click and hold this icon, it becomes a draggable alias for the file. You can then use that alias much as you would the file itself (as if you had dragged it from the finder) – but one thing you can’t do is delete the file by dropping it in the trash.
Trashy is a simple program to fix that. Put it in your dock, and it will send anything you drag onto it into the trash. Click here to download Trashy.
Here’s the entire source code applescript, if you’re curious (or just naturally suspicious of running random programs you found on internet, as you ought to be):
on open fileList
tell application "Finder"
repeat with f in fileList
set n to 0
repeat while class of f is alias file
if n is less than 5 then
set n to n + 1
set f to original item of f
end if
end repeat
move f to the trash
end repeat
end tell
end open
on run
tell application "Finder" to open the trash
end run
…
→ 24 March 2008.
Tags:
programming,
application
[I made this]
A Lightweight Metadata manager for OSX, allowing you to easily tag and rate any type of file (which is then indexed by spotlight). This is basically my iPhoto replacement now, after spending a week trying to fix its broken database, orphan files, duplicates and all that rubbish. This is much simpler, and it can be used to tag any type of file I want.
This is the result of 2 days work, and just 400 lines of code. That’s pretty decent in my book, the combination of python and cocoa is a pretty powerful beast. Once you get past all the runtime errors and pyobjc bridge troubles, that is…
(view link)
…
Photo.99
→ 12 March 2008.
Tags:
programming
According to matt, I just made milk come out of Python’s nose.
[i made this, although I’m hardly proud of that fact]
For those who care (or are thoroughly confused), this is a python function to find out where an alias file (the mac’s version of a shortcut or soft link) actually points to. And no, it really shouldn’t have to be this hard.