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.

(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.

 

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.

(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 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)

Jun 9, 2013

When did dependency management get so complicated?

This evening I wanted to start hacking on a project of mine, which is a simple WordPress theme. My main development machine was being used by somebody else, so I decided to boot up my old Sony Vaio running Ubuntu. It’ll be simple, I thought. I’ve just got to clone the repo, run npm install, bower install, and grunt build, and I’ll be good to go. I was wrong.

First, the version of npm installed on the laptop is apparently so out-of-date that it can’t run the install. So I let it update itself (and all the other packages I have installed - why not?) with sudo npm -g update. Being a Sunday night, my broadband connection is running spectacularly slow, so the update process takes about 10 minutes at 40kB/s. But hey, at least now I can run npm install, right?

Nope. Now npm is throwing some errors with unhelpful messages, but that’s fine, I’ll just trawl through the error log. 5 minutes later, I figure out that ~/tmp belongs to root (probably from running npm update as root). OK, fine, I’ll change the permissions and try again. This time npm install works! But of course, my connection is so horribly slow and grunt has so many dependencies that the install process takes over 15 minutes.

(Read more)

May 20, 2013

Blazing fast WordPress with Nginx and Memcached

Inspired by Eric Mann’s post on caching WordPress with Redis, I thought I’d experiment with a similar setup using Memcached. Any in-memory caching system should work just as well, but I’ve chosen Memcached because it’s already running on my server and because PHP already has a built-in libmemcached API.

My current setup is Nginx and PHP-FPM, with WP Super Cache. The cache is saved to the filesystem, allowing Nginx to serve static files (which it is very good at) without needing to pass any requests to PHP. This setup has worked very well, so I’ll be using it as a baseline.

To use Memcached, every request needs to be passed to PHP. My gut feeling was that this would be slower than serving static files with Nginx due to the overhead of spinning up a PHP process for each request.

Benchmarks

To find out which of the two setups was faster, I measured the following metrics using WebPagetest and Blitz :

(Read more)

May 20, 2013

Increasing the size of the LISH console

If you’ve used Linode’s LISH console to get remote access to your server, you’re probably familiar with the way the console wraps everything to 60x20 (columns x rows) - even when you’re connected via ssh in a much larger terminal.

(Read more)

Nov 14, 2012

Setting up your editor

Setting up your editor correctly can make working with other developers much less painful. Below are some things that I believe every developer should do when editing source code. Any good IDE or editor should have settings to do these things automatically - the points below are paired with their Sublime Text setting.

(Read more)

Oct 12, 2012

Non-tech books I should read

This post is to help me keep track of non-tech books that I would like to read.

Breakfast of Champions by Kurt Vonnegut

Slaughterhouse-Five by Kurt Vonnegut

Cat’s Cradle by Kurt Vonnegut

Do Androids Dream Of Electric Sheep by Philip K Dick

Neuromancer by William Gibson

Ham on Rye by Charles Bukowski

(Read more)

← Older Posts Newer Posts →