Apr 26, 2015

Cabal: Installing readline on OSX

I’ve had trouble installing the readline package on a few separate OSX installations, so I figured it was worth writing the solution down.

When running cabal install for a package which depends on readline (or simply when running cabal install readline), Cabal exits with errors along the lines of

Configuring readline-1.0.3.0...
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for GNUreadline.framework... checking for readline... no
checking for tputs in -lncurses... yes
checking for readline in -lreadline... yes
checking for rl_readline_version... yes
checking for rl_begin_undo_group... no
configure: error: readline not found, so this package cannot be built

The problem is that Cabal is not aware of the location of the readline lib. My workaround is to specify the location of the lib whenever running these commands:

$ cabal install readline --extra-include-dirs=/usr/local/Cellar/readline/6.3.8/include/ \
                         --extra-lib-dirs=/usr/local/Cellar/readline/6.3.8/lib/ \
                         --configure-option=--with-readline-includes=/usr/local/Cellar/readline/6.3.8/include/readline \
                         --configure-option=--with-readline-libraries=/usr/local/Cellar/readline/6.3.8/lib/

Your paths may differ slightly if you have a different version of readline installed. You can check this with

$ ls /usr/local/Cellar/readline
6.3.8
(Read more)
Oct 31, 2014

Transitioning to a new keyboard layout

I’ve long been considering switching to a different keyboard layout. I tend to type with mostly my forefinger and middle finger, only using my ring and pinky fingers occasionally to stretch out to the modifier keys. Despite this, I still manage to type at around 120WPM on a staggered QWERTY keyboard.

Thinking back, I probably started teaching myself to type at a reasonable speed around age 10. I’m now in my mid-twenties. My typing technique (or lack thereof) never really bothered me, but 15 years of typing with poor technique has started to take its toll. Recently I’ve started experiencing hand fatigue, and I’m beginning to see early signs of RSI. So I figure now is the perfect time to make some changes to the way I type.

(Read more)
Aug 2, 2014

JavaScript Performance: Variable Initialization

Initializing variables properly in JavaScript can have significant performance benefits. This can be shown with a simple synthetic benchmark.

notype.js

var x = null;

for (var i = 0; i  1e8; i++) {
    x = 1 + x;
}

withtype.js

var x = 0;

for (var i = 0; i  1e8; i++) {
    x = 1 + x;
}
(Read more)
May 25, 2014

A Hacker's Guide to Git

A Hacker’s Guide to Git is now available as an e-book. You can purchase it on LeanPub.

Introduction

Git is currently the most widely used version control system in the world, mostly thanks to GitHub. By that measure, I’d argue that it’s also the most misunderstood version control system in the world.

This statement probably doesn’t ring true straight away because on the surface, Git is pretty simple. It’s really easy to pick up if you’ve come from another VCS like Subversion or Mercurial. It’s even relatively easy to pick up if you’ve never used a VCS before. Everybody understands adding, committing, pushing and pulling; but this is about as far as Git’s simplicity goes. Past this point, Git is shrouded by fear, uncertainty and doubt.

(Read more)
May 9, 2014

Understanding JavaScript: Inheritance and the prototype chain

This is the first post in a series on JavaScript. In this post I’m going to explain how JavaScript’s prototype chain works, and how you can use it to achieve inheritance.

First, it’s important to understand that while JavaScript is an object-oriented language, it is prototype-based and does not implement a traditional class system. Keep in mind that when I mention a class in this post, I am simply referring to JavaScript objects and the prototype chain – more on this in a bit.

Almost everything in JavaScript is an object, which you can think of as sort of like associative arrays - objects contain named properties which can be accessed with obj.propName or obj['propName']. Each object has an internal property called prototype, which links to another object. The prototype object has a prototype object of its own, and so on – this is referred to as the prototype chain. If you follow an object’s prototype chain, you will eventually reach the core Object prototype whose prototype is null, signalling the end of the chain.

So what is the prototype chain used for? When you request a property which the object does not contain, JavaScript will look down the prototype chain until it either finds the requested property, or until it reaches the end of the chain. This behaviour is what allows us to create “classes”, and implement inheritance.

(Read more)
Mar 10, 2014

Defining readable code

Code readability is something that I often bring up during code reviews, but I often have trouble explaining why I find a piece of code to be easy or difficult to read.

When you ask programmers how to make code easier to read, many of them will mention things like coding standards, descriptive naming, and decomposition. These things actually aid in making code easier to comprehend rather than easier to read. For me, readability is at a lower level, somewhere between legibility and comprehension.

Legibility - Readability - Comprehension

At the lowest level is legibility. This is how easily individual characters can be distinguished from each other, and can usually be boiled down to the choice of font, as well as the foreground & background colours.

At the highest level is comprehension, which is the ease in which a block of code can be fully understood. Decomposition, naming conventions and comments are just a few of the many ways to improve comprehension.

Readability sits between these two. This level is a little harder to define, but I believe it comes down to two main factors: structure and line density.

(Read more)
Sep 30, 2013

HTTP status as a service

Using Node.js* you can run a simple “HTTP status as a service” server. This can be useful for quickly checking whether your application handles various status codes.

var http = require('http');

http.createServer(function (request, response) {
  var status = request.url.substr(1);

  if ( ! http.STATUS_CODES[status]) {
    status = '404';
  }

  response.writeHead(status, { 'Content-Type': 'text/plain' });
  response.end(http.STATUS_CODES[status]);
}).listen(process.env.PORT || 5000);

This will create a server on port 5000, or any port that you specify in the PORT environment variable. It will respond to /{CODE} and return the HTTP status that corresponds to {CODE}. Here’s a couple of examples:

$ curl -i http://127.0.0.1:5000/500
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain
Date: Mon, 30 Sep 2013 14:10:10 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Internal Server Error%
$ curl -i http://127.0.0.1:5000/404
HTTP/1.1 404 Not Found
Content-Type: text/plain
Date: Mon, 30 Sep 2013 14:10:32 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Not Found%

This is a really simple example, and could easily be extended to let you specify a Location header value for 30X responses.

(Read more)
Sep 6, 2013

Converting Bootswatch themes to SASS/SCSS

There’s a fairly quick way to convert Bootswatch themes to Sass (which you might want to do if you use something like sass-bootstrap).

Simply download the theme’s variables.less and run the following find/replace patterns against it:

Variables

Find (regex): @([a-zA-Z0-9_-]+)

Replace: \$$1

Mixins

Find: spin(

Replace: adjust-hue(

This is all I’ve found in the themes that I’ve tried.

(Read more)
Aug 20, 2013

Getting Internet Sharing to work on OSX 10.8

I noticed that the Internet Sharing functionality didn’t work on my Macbook Air (running OSX 10.8 - Mountain Lion). This is because the Air’s DNS server (BIND) isn’t configured correctly.

For me, the fix was pretty simple. Edit /etc/com.apple.named.proxy.conf by running sudo nano /etc/com.apple.named.proxy.conf in a terminal, and change

forward first;

to

forward only;

Then turn Internet Sharing off and on again.

The annoying thing is that OSX seems to restore the BIND config the next time you turn Internet Sharing off, so you need to remember to change it each time.

(Read more)
Aug 16, 2013

Force Bower to clone from https:// instead of git://

Most Bower packages will be fetched using a git:// URL, which connects on port 9418. This can be problematic if you’re behind a firewall which blocks this port.

You can get around this quite easily by telling Git to always use https:// instead of git://:

git config --global url.https://.insteadOf git://
(Read more)
Aug 7, 2013

Dishonest comments

One of my favourite Ruby Rogues episodes (What Makes Beautiful Code) has a short section where the Rogues talk about the concept of dishonest code. David Brady wrote a really good piece on this, which I highly recommend reading.

What I want to talk about is a more specific variant of dishonest code: dishonest comments.

Take this code, for example:

$('a').click(function(e) {
    e.stopPropagation();
    e.preventDefault();
});

If you’re not familiar with JavaScript events, e.stopPropagation() will stop this event from bubbling up to other event handlers. Now, what if somebody decides that the event should bubble up? They might do something like this:

--- a/example.js
+++ b/example.js
@@ -1,4 +1,4 @@
 $('a').click(function(e) {
+    // Let the event bubble up to the next handler
-    e.stopPropagation();
     e.preventDefault();
 });

This is pretty common practice; a developer will leave a comment so that the next person understands why the e.stopPropagation() is gone.

(Read more)
Aug 7, 2013

Don't use Git's autocorrect feature

Quite often I’ve accidentally typed “git” twice. Usually this is fine, and Git just does something like this:

$ git git diff
git: 'git' is not a git command. See 'git --help'.

Did you mean this?
    init

But I recently turned on Git’s autocorrect feature, to see what it was like (git config --global help.autocorrect 1). The results were… interesting:

$ git git diff
WARNING: You called a Git command named 'git', which does not exist.
Continuing under the assumption that you meant 'init' in **0.1 seconds** automatically...
fatal: internal error: work tree has already been set
Current worktree: /nfs/personaldev/vagrant/mobileweb-v2
New worktree: /nfs/personaldev/vagrant/mobileweb-v2/diff

This is really bizarre behaviour. The fact that it wants to autocorrect it to git init is sort-of okay. But rather than giving me the option to confirm that this is what I want, Git gives me a whole 0.1 seconds to hit Ctrl+C before it automatically runs the command for me.

Thankfully, git init isn’t a very destructive command. I was lucky that the only side effect of this was that Git created a new directory called diff. I can’t help but wonder what would’ve happened if Git decided to autocorrect to a more destructive command like reset, checkout, or gc.

The lesson here? Don’t use Git’s autocorrect. It really sucks.

Update: m_bright pointed out that the value of help.autocorrect is actually how many tenths of a second Git will wait before automatically executing the command. So something like git config --global help.autocorrect 10 would give you 1 second before the command is executed, which is probably slow enough to let you cancel any mistakes, and quick enough to still be useful.

(Read more)
Aug 1, 2013

Installing PHP on Debian without Apache

When you apt-get install php5 on a Debian/Ubuntu server, you’ll notice that APT will automatically install a bunch of apache2 packages as well. This can be pretty annoying if you’re planning on using another web server (or no web server at all).

If you take a look at the package dependencies (Debian/Ubuntu) you’ll see why this happens - php5 needs one of either libapache2-mod-php5, libapache2-mod-php5filter, php5-cgi, or php5-fpm. APT doesn’t care which package it installs; it just picks the first package that satisfies the dependency, which is why you get the apache2 packages.

You can get around this by installing one of the other dependencies before php5. For example, apt-get install php5-fpm php5 or apt-get install php5-cgi php5.

(Read more)
Aug 1, 2013

Using SSH agent forwarding with Vagrant

Sometimes you’ll want to use your local SSH keys on your Vagrant boxes, so that you don’t have to manage password-less keys for each box. This can be done with SSH agent forwarding, which is explained in great detail on Unixwiz.net.

Setting this up is fairly straightforward. On the host machine, you need to add the following to ~/.ssh/config (which you should create if it doesn’t exist):

host your.domain.com
    ForwardAgent yes

You need to replace your.domain.com with either the domain or the IP address of your Vagrant box. You can wildcard this with host *, but this is a really bad idea because it lets every server you SSH to access your keys.

Once you’ve done that, just run ssh-add to ensure you ensure your identities are added to the SSH agent.

Now, add the following to the config block in your Vagrantfile:

config.ssh.forward_agent = true

That’s all it takes. You can make sure it worked by comparing the output of ssh-add -L on both the host machine and the guest box.

(Read more)
Jul 17, 2013

Worst fonts for programming

There are plenty of discussions about which font is the best for programming. The problem is, there are so many “best” fonts that it’s difficult to choose one. Rather than have an exhaustive list of “best” fonts for programming, wouldn’t it be easier to simply know which fonts to avoid?

(Read more)