Perhaps you considered Mac OS X 10.7 Lion
While I appreciate a new version as much as the next tech guy, I wouldn't recommend anybody to update yet.
- it's slow - connecting to 127.0.0.1:8080 took me 62 seconds, mundane tasks like cmd-tabbing lags sometimes, etc. Something's off.
- exaggerated animations - due to their graphical intensity, they have perceptible rendering times... in a desktop UI. Does not go.
- extremely cumbersome to use without a trackpad - means you sit with the computer in your lap rather than plug in external keyboards etc.
- they inverted the scroll direction. What the hell, man. "Natural scrolling"? Sheer gimmick value.
- Launchpad... I'm not sure why you would prefer a modal interface that only allows dragging as mode of operation. Gimmick again.
- Mission Control seemed like a good idea but it turns out you can't rearrange spaces, nor rename them - so rather "Mission Happenstance" than Control (and don't get me started on the auto-rearrange feature)
- you can now scroll past the beginning and end of the content, and very few applications are designed for this leading to UIs looking goofy
- "Press and hold" disables keyboard repeat... for most keys. (The feature itself only works on Apples own layouts, with no document detailing how to implement this for your own keyboard layouts having been published.)
- Browser back/forward with three finger swipes no longer work, Apple decided to use them for Spaces - you have to use the keyboard or nav buttons, unless you happen to use Safari which now uses horizontal two-finger swipes
- refreshing new UI look
- fullscreen now integrates with Spaces
- umm... I guess the new UI is pretty neat, yeah
Scaling Web Applications & Tower Defenses
If I were to try to teach a 15-year-old how to scale well on the Internet, I would let him play some Warcraft III tower defense map.
The analogy is pretty striking really: you have a more or less constant stream of visitors (creeps), and your goal is to not only meet the performance needs (deal enough damage), but also one of efficiency: how much gold do you need to deal enough damage to kill all the creeps -- or how many dollars do you need to perform well enough to handle all the traffic.
I'm not going to tell you how, because the TD analogy also lifts an interesting aspect: unless you know how the game works and what the alternatives are, you're going to suck at it. Perhaps less than some, probably more than others, but you're going to suck nonetheless.
Thought I'd let you know.
Qmail woes
I wouldn't recommend anyone ever to use qmail, no matter how beautiful the architecture might strike you. It's confusing, takes a solid two hours to even find a document to read, and there doesn't at all seem to be much community support for it. Most of the time you're left to your own devises with a--excuse my saying so--retarded mail server.
Maybe you know about Transport Layer Security, or TLS for short. It's a common enough thing, SMTP servers are known for their use of TLS. Well, Qmail probably isn't, because the only TLS support there is is a huge patch whose website is presently down.
As it turns out, one of these days my TLS support had just given up. Qmail doesn't tell you though, oh no -- not at all. You have to dump the I/O it does with Gmail to know anything is going wrong.
If I were you, and I was using Qmail with TLS support (like I do), then I'd check if my SMTP server goes wonky after I send STARTTLS. Mine did, and didn't tell me.
Why does this matter? Well, as it turns out, Gmail doesn't deliver messages when TLS fails like this, and I can't really blame them because my server advertised support for TLS.
So in short: stay away from Qmail, don't accept patches from strangers and don't wake up too late.
RTNETLINK complaining about "No buffer space available" (also SIOCSIFADDR)
I'm writing this to save somebody a headache.
My router does IPv4 and IPv6, and has been doing so for a while. I started noticing that when connecting to my own server from my own home, it would take a while. I whittled it down to it trying to connect with IPv6 first, failing and then falling back to IPv4 which worked fine.
Now, why had my IPv6 died? To cut a long story short, here's why:
router # ip link show eth1
4: eth1: mtu 576 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:bf:21:b2:52 brd ff:ff:ff:ff:ff:ff
Look closely. Closer. The MTU is 576. No buffer space? Well, that just means the MTU is too low for IPv6! The error mesasge couldn't have been more clear! Err...
router # ip link set eth1 mtu 1500
BAM! Now it works again.
So why was the MTU set to 576? dhcpcd set it to that value! A-ha. Apparently this also happens to dhclient, and I guess the two are intertwined in some weird open-source way. My more persistent solution?
router # unlink /lib/dhcpcd/dhcpcd-hooks/10-mtu
BAM! Now it won't break for a while.
Graphviz's dot: PNG not recognized
This is a post not only to relieve some frustration, but also to help some other poor fellow with this problem as I think it will inevitably crop up.
I just wanted acyclic graphs in my Sphinx documents. That was it.
So, I installed Graphviz with Brew, expecting it to work... But no:
~ $ dot -Tpng Format: "png" not recognized. Use one of: canon cmap cmapx cmapx_np dot eps fig gv imap imap_np ismap plain plain-ext ps ps2 svg svgz tk vml vmlz xdot
I installed it on my own. I varied the configuration. Everything. I searched mailing lists. Then, I found a discussion saying Graphviz cannot be relocated without running dot -c -- hmm:
~ $ sudo dot -c Warning: Could not load "/usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib" - file not found Warning: Could not load "/usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib" - file not found ~ $ ls "/usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib" /usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib
What? It's right there for f---'s sake!
I even did an otool -l on the file in question, to see that the shared libraries it loaded were in the correct places, and they were!
So, my last effort, a shot in the dark: load it with ctypes, see what it says. After tearing out the hair on my skull, this:
/usr/local/Cellar/graphviz/2.26.3 $ python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.CDLL('/usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ctypes/__init__.py", line 345, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(/usr/local/Cellar/graphviz/2.26.3/lib/graphviz/libgvplugin_gd.6.dylib, 6): Library not loaded: /opt/local/lib/libiconv.2.dylib
Referenced from: /usr/local/Cellar/gd/2.0.36RC1/lib/libgd.2.dylib
Reason: Incompatible library version: libgd.2.dylib requires version 8.0.0 or later, but libiconv.2.dylib provides version 7.0.0
>>>
Why the fork didn't it just tell me that instead?
The solution of course is to rebuild GD since it links against a libiconv that not only is outdated, but has also been removed.
Apple Bullshit: iPhone text input
I'm an Apple user. I have a MacBook Pro, and an iPhone. I get the whole "Apple sucks" thing about every day (mostly from Android/Linux users, hm).
But honestly, Apple? Why can't my iPhone learn new words? Why is that not a possibility? My first cellphone could be taught new words. It adapted to my vocabulary over time.
The iPhone pretends to. It stops making some corrections. For example, writing "åå" used to correct to "på" ("on"), but because I actually used that correction a lot (convenient to type the same character twice), the iPhone then stopped correcting me on that. Huh.
Let me briefly introduce you to the letter Ä. It sounds just like E in many cases, and the glyph comes from an A with a lowercase "e" above it. In Norway it is known as Æ. In Swedish, if you end a word with Ä, it isn't uncommon to add an E to the end. Like the word for "no", "nej", is usually written "nä", but since that's so short, a lot of people (myself included) write "näe". What does the iPhone do? Corrects it to "när". Means "when". Thanks.
The worst part about it all is the interface workflow Apple chose. They must've thought their algorithm is never wrong. Why the f*** else would you make corrections to my text when I hit "Send"? Ridiculous.
And why am I not allowed to add to my dashboard an item that disables 3G or cellular data altogether? Because Apple engineers failed to conceive of the need? Why the hell does the functionality of a piece of electronics in my hand depend on people I don't know in f***ing America? Ridiculous.
Because that's another thing: toggling settings on the iPhone is awkward at best. You have to go into the Settings application, navigate your way through sections upon sections of settings, and then toggle your favorite setting. For example, I as I said disable 3G (because my battery holds 3-4 days with it off, and less than 24 hours with it on) - how?
Why simple, just push Home once. You push twice, sorry, try again. Then, find the Settings app, you're going to have to have it on your first page anyway so you might as well move it already. Navigate into the "General" subcategory. Find the "Network" subcategory and tap on it, it's a little bit down. Find "Cellular Data" and toggle the switch.
Frustrating as hell is what it is. People constantly congratulate themselves for using Apple, saying "here somebody thought about the UI." Bull f***ing shit, they sat in focus groups and alleviated the common usecases for the phone. A phone that does not allow power users to wield it fully.
Speaking of bullshit UI from Apple, iTunes, more precisely iTunes export feature. iTunes is often hallowed as the crown jewel of amazing UI. I think more like crown turd of craptastic UI, but I digress.
iTunes has this concept of your organizing your music into a library. Right. You drag stuff into a library, files or whatever. If you lose your harddrive, sorry that's your library with it -- syncing your iPhone won't help, because the new iTunes install will actually clean out your iPhone. Thanks.
Anyway, you export things from a library, you expect them to be exported, right? Not duplicated. Guess what happens when you export stuff in iTunes? You get the export progress UI, then when the export is done, bam. Gone. The files you exported are now in your library, looking exactly like the files you exported from, so you don't know which is which.
Wait what. Why... What. Why the f*** would I want to do that? Makes no sense at all. I have an album. I'm creating a zip of an album so my mate can listen to it (this is legal, like passing on a CD).
iTunes helps me in the following way: the music I bought on iTunes Music Store is labelled with my e-mail. What is up with that, Stasi Apple? Secondly, it'll let me "Create AAC version" (or whatever my exporting options are set to). This then results in the album being duplicated in my iTunes folder, with no simple way of determining which of the two items is the latter duplicate.
In general though, OS X is great. The fact that you can query almost any service from a shell really matters. But when it comes to iOS and embedded devices in general, Apple is a whole other story. Apple will never let you browse or edit the filesystem of an iPhone. Ever.
Let that sink in for a moment.
The Number One Reason Nobody Uses AIM

I type at my normal rate, and that is considered "too quickly"?
If you're the AIM engineer behind this, give me a shout and I'll teach you exactly how to implement a simple token bucket contraption, so people can burst when they need to.
Pratical mmap usage
I just finished a part of an iPhone application in which I got to use an awesome technique known as mmap.
First: what is mmap, and why is it so awesome? What mmap lets you do is basically to tell the operating system that you would like a file, any file, to be mapped in virtual memory.
So where you normally would allocate a chunk of memory, write and read to it as one usually does with memory, you would instead get a memory address on which the contents of a given file starts.
My particular application of mmap was in the writing and displaying of the awesome Seismometer app's recording functionality.
The demands were pretty high, even though users of the application might not notice it (because it works so well):
- The measurements come in at 60Hz, which equals about 2kB of data per second;
- a recording should be able to span hours, otherwise the recording feature is useless;
- the code should be quick enough to work without being sluggish on iPhone 2G, which is an embedded device running at 412 MHz
One of the problems I had using mmap was that the mapped memory area has to be a multiple of the page size (which is 4kB), and to the contrary of OS X's mmap man page, the offset into the file too needs to be page aligned.
This basically means that when the Seismometer wants to show record #782, one simply has to juggle some numbers to get the proper page in the file, and the offset into that page.
So what I ended up doing was something like this pseudo-code:
measurement *find_record_num(int recnum, int *numrecs); void display_some_measurements(int recstart, int numrecs) { int recs_left = 1; /* number of records left to read */ measurement *current; do { if (!--recs_left) { current = find_record_num(recstart, &recs_left); } else { current++; } display_record(current); } while (--numrecs); }
Then, find_record_num would act as a pager within the recording file, and remap the memory area when desired.
Of course, since I did this in Objective-C, functions had very long and verbose names with unnecessary adjectives stringed together to form a long sentences which never seemed to end quite like this one. :-)
Anyway, thought I'd share this since I found mmap a fascinating concept, and finally got a chance to try it out.
Also, if you would like to try out the Seismometer application on your iPhone, I've got a pair of promo codes, so leave a comment and I'll get back to you!
Backups smackups.
A great man once said "you should have backups."
I didn't back up my company's page, sendapatch.se, because I thought it was so small and insignificant. The problem is that you don't realize how much time something is worth. That is, until you sit down and try to rewrite it.
Anyway, site is back and all is fine -- though I doubt a lot of people will see this since the server which hosted sendapatch.se also hosted an RSS filter which Planet Python polls for my blog.
This might seem silly: git pull
So, as a bilingual person, you very often borrow terms from one language into the other. Examples include how Swedish developers will say "libbet" for "the library", but crucially, only for software libraries.
The very reason we bilingualists borrow words so often is that we feel the non-native word is a narrower metaphor for what we're trying to say.
This happens for pretty much any IT-related verb, I say "Jag pushar branchen till ditt repo" where neither push, branch nor repo are actual Swedish words. ("I push the branch to your repository".)
Why is this a problem, and why do I bother telling you about it? It surely is a natural phenomenon for any bilingualist, and not anything new or unheard of.
It's a problem because of the word "pull". See, Swedish has a particular suffix for verbs in present tense. It's "-a". This, applied to "pull", yields "pulla".
The word "pulla" already exists, which is usually not an issue, were it not for what the word means: "pulla" is colloquial Swedish for "female masturbation", or "fingering oneself".
So, to me, the following conversation I had with a fellow Swedish coworker the other day makes total sense (and you can probably guess what it means):
me: okej, najsme: även om du pullat?coworker: pullade för ~5min sen
I ask if he has pulled the latest changes, he says he pulled me five minutes ago. Nothing odd about that. Except that this, interpreted by an average Swedish person, reads:
me: okay, niceme: even if you fingered yourself?coworker: I fingered myself about five minutes ago
You can see how this can get pretty awkward when around people who have no idea about these matters, as is not uncommon.
So please, dear reader, I call upon you to change this name to something more bilingually friendly. Something neutral.
A little off-topic
Oh man, this one's great.

On branching... Wait no, on committing
So, mr. Bennett is causing a ruckus as always, discussing the benefits of Hg over Git.
While I heartily agree that Git branches are sort of a stretch of the implementation to match the metaphor, and I'm sure Hg does it way better (I've used Hg but I use Git much more often.)
However, Git has one feature that just makes it so much better: the staging area.
Coincidentally, the staging area seems to confuse many new users (and Hg users for sure) -- in essence, it's what you're preparing to commit. I don't really care much for Git branches (I just know they're easy to merge, and merges do preserve history).
What it lets you do, and what Git is very good at, is build a commit and refine it before you publish it.
In Subversion I usually make commits that touch files that just don't "deserve" their own commit, and not mention it in the commit message. It could be that I changed a typo in the docstring for a function or something.
It's not like I wouldn't want to commit it by itself, but when there are a couple of such changes in your working directory, with Subversion, you just go "Meh." and commit it all.
With Git, however, you're encouraged to only commit the changes that belong to one commit. The best, most powerful feature in Git, which Hg sadly lacks, is the ability to add parts of a file to a commit. This is, coincidentally, where Subversion is impossible to work with.
So in short, mr. Bennett, committing is what makes me choose Git over Hg.
MacVim Quicktip: Tab switching with Command-[0-9]
Up until now, I've been wondering how to bind Command hotkeys in MacVim. The answer is <D-foo>.
So, because I simply love Cmd-[0-9] and Cmd-Shift-Right/Left in my Terminal and browser, here's how to bind these in MacVim:
noremap <D-1> 1gt noremap <D-2> 2gt noremap <D-3> 3gt noremap <D-4> 4gt noremap <D-5> 5gt noremap <D-6> 6gt noremap <D-7> 7gt noremap <D-8> 8gt noremap <D-9> 9gt noremap <D-9> 10gt noremap <D-S-right> gt noremap <D-S-left> gT
SSH agent forwarding and GNU screen
I'm an avid user of both gateway-based SSH and GNU screen.
By gateway-based SSH, I mean first SSHing to one machine and then from there getting access to the machine I was looking for, as a security measure or just because the machine in question has no external IP address.
This, up until now, has never worked for me when using OpenSSH's excellent agent forwarding.
Agent forwarding is what it sounds like - your SSH agent (the one that keeps your unlocked SSH keys in memory) gets forwarded to another machine. This is enabled with the -A option to OpenSSH.
Commonly, I'd get an issue like this:
laptop $ ssh -At gateway ssh -A svett
svett $ screen -r
svett $ svn up
Password:
I mean, who the hell uses passwords these days anyway? So, on to the solution. It's quite simple, actually.
OpenSSH's forwarding is pretty simple, and the reason it doesn't work in the above case is that the screen session was started with another SSH agent tunnel, which is now dead. How do we fix it? Simple. Just fix your environment.
laptop $ ssh -At gateway ssh -A svett
svett $ echo $SSH_AUTH_SOCK
/tmp/ssh-abcdef/agent.1234
svett $ screen -r
svett $ export SSH_AUTH_SOCK=/tmp/ssh-abcdef/agent.1234
svett $ svn up
At revision 1234.
And that's all there is to it. You could even set up aliases for this if you do it often enough, but then again then you'll be dependent on that alias on every machine you use, so...
OS X Tip: Change shell to that of frontmost Finder window
I was looking for any integration between Finder and Git (because I like GUIs sometimes. (I know about GitX.))
I came across this instead, a bash function (which works in zsh) that changes directory to that of the frontmost Finder window. It's convenient!
cdfinder() { cd "$( /usr/bin/osascript <<" EOT" tell application "Finder" try set currFolder to (folder of the front window as alias) on error set currFolder to (path to home folder as alias) end try POSIX path of currFolder end tell EOT )" }
Reference: asktherelic.com/.../osx-terminal-and-finder-integration/
