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. (more…)

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.

*Well, you could use anything really. I’m just using Node.js since JavaScript is my language of choice.

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.

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.

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://

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.stopPropogation();
    e.preventDefault();
});

If you’re not familiar with JavaScript events, e.stopPropogation() 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.stopPropogation();
     e.preventDefault();
 });

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

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.

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.

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.

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?

Brush Script MT

This font was created in 1942 by Robert E. Smith. It’s designed to look like the characters have been handwritten with an ink brush. This font will make you feel right at home if you grew up writing your code with an ink brush. Otherwise, don’t use it.

Brush Script MT

Chiller

A relatively modern font (1995), Chiller is supposed to be very legible even at small sizes. This font is great for giving your code that “spooky” feel. However if you prefer emotionless, monospaced fonts, Chiller is probably not for you.

Chiller

Comic Sans MS

By far the most loved font on the web, Comic Sans has been bringing joy to peoples’ lives since its inception in 1994. Coding in Comic Sans is fun, and reading code in Comic Sans is even funner-er. Unfortunately, some people don’t like Comic Sans, so you should avoid using it unless you enjoy being ridiculed by your colleagues.

Comic Sans MS

Impact

Created in the Swinging Sixties by a fellow named Geoffrey Lee, Impact was intended for headlines. Why should headlines be the only text with emphasis, though? Using Impact will give your code the emphasis it deserves by making every single line a headline. The downside is that prolonged exposure to Impact can cause developers to read everything in a yelling voice. If this is a problem for you, avoid using this font.

Impact