about:benjie

Random learnings and other thoughts from an unashamed geek

Octopress: CoffeeScript/JS Code Toggle

| Comments

Dru Riley asked via a comment how I achieved the CoffeeScript/JS highlighting switch on my blog which looks like this:

.coffee.js<-- These buttons toggle CoffeeScript/JavaScript
1
2
3
4
CoffeeScript is 'awesome'
dance() if you.love CoffeeScript
i.love CoffeeScript
yay()

The answer: a hack. I don’t code ruby, so I couldn’t figure out how to do it neatly (or even if I could - feedback welcome!). The easiest way for me to do it was just to modify plugins/backtick_code_block.rb, then add the JS and CSS to make it work.

If you want to see how I did it, or do it yourself, here are my diffs:

Node.JS SSL Certificate Chain

| Comments

I’ve just discovered that one of our servers is not serving up it’s SSL certificate chain correctly. This is fine for modern web browsers who trust the COMODO certificate, but for older browsers/operating systems you need to support higher up the trust chain.

Previously I followed the technique in this article, but it turns out that the ca parameter of the TLS/HTTPS server should be an array. More than this, you cannot just feed it an array containing your chain file as a string/buffer (i.e. [fs.readFileSync("/path/to/mydomain.ca-bundle")]) since the Node TLS module only reads the first certificate in each entry of this array.

To solve this you can parse your existing certificate chain:

Node, Websockets, Safari and Emoji

| Comments

It seems emoji break websocket.io (the websocket library used by socket.io). They seem to cause the message payload to terminate prematurely.

After a morning of research on the subject, I was pointed at mranney’s essay on the subject by `3rdEden on irc.freenode.net/socket.io. It turns out that the issue is due to V8 (the JavaScript engine used by Node.JS) using the UCS encoding internally rather than the more modern UTF-16. Emoji require 17 bits (their code values are larger than 65,535), which is more than UCS can give (UCS uses exactly 2 bytes (16 bits) to represent every character, so it only supports values between 0 and 65,535; whereas UTF-8 and UTF-16 use a variable number of bytes).

I’ve confirmed with WireShark that Safari is sending valid UTF-8 (11110000 10011111 10011000 10010011 or hex: f0 9f 98 93, which gives the Unicode codepoint U+1F613 😓). So I know it’s Node’s issue receiving and processing it.

This is probably one of the reasons that Google Chrome doesn’t support Emoji - check out this page in Chrome, then view it in Safari to see what you’re missing! (Chrome uses the V8 engine.)

Solution

You could base64-encode your payload, or simply escape()/unescape() it. Or you could trim anything outside of UCS. Or you could do a custom encode/unencode such as this one. I’m not really happy with any of these, so I’m still looking for a solution.

Update

In the end I implemented this (see below) on the client side, and left the data encoded server side. All clients are responsible for encode()ing characters when sending, and decode()ing upon receiving (whether that be via websockets or HTTP). It seems to work quite well and doesn’t massively inflate the content-size for ASCII and possibly more[citation needed], so I’m relatively happy with it. Besides it’s midnight and I need to get some sleep.

.coffee.jsPatch UTF-8 issues
1
2
encode = (s) -> unescape encodeURIComponent s
decode = (s) -> decodeURIComponent escape s

Switching to Vim: The Easy Way - Commands

| Comments

Continuing from what we learned in part 1 (installing and vimtutor), I’d now like to focus on the fundamental commands in Vim.

Commands

Vim commands are formed from a combination of verbs and targets. The targets could be objects (words, sentences, paragraphs, lines, the contents of parentheses) or movements (jump to end of word, jump to end of paragraph, jump forward until the letter ‘e’, etc). Forming objects generally involves the use of a modifier. You can also add a count to perform the action count times.

Verbs

Here’s some example verbs (don’t try and learn them all at once!):

Switching to Vim: The Easy Way - Installing/Vimtutor

| Comments

This post is the first in a series aiming to encourage you to switch to Vim without going through that first period of significantly reduced productivity that you’re bound to go through if you follow certain Vim gurus advice such as disabling your arrow keys and what not. (This is good advice once you’ve fully mastered the basics of Vim as a way to kick bad habits, but I certainly wouldn’t advise starting that way!)

Installing Vim

I recommend you start with a graphical Vim app so that you can use your mouse to click around. Ultimately you will rarely if ever use your mouse (moving your had that far will seem really inefficient) but to start with it can significantly alleviate the frustration of being slow with the movement commands.

Mac

If you use Homebrew then you can simply issue

1
$ brew install macvim

And voila, you’re done. Otherwise take a look at the MacVim instructions.

12 Years Together!

| Comments

Today marks the 12th anniversary of Jem and I being a couple. We met when we were 13 on a Scout camp site near Southampton and immediately became pen-pals. We wrote each other frequently, meeting up when we could, and soon fell in love. That love, despite being the painfully intense all-encompassing love of teenagers, has matured, strengthened and grown over time. We’ve now been married for over 3 years and our son Xander is 16 months old.

I want to take this opportunity to thank my wife for everything. Her constant loving support helps me in every aspect of my life from fatherhood to business to helping me deal with my health problems. I honestly don’t know what I would do without her.

❤ Thank You, Jem ❤

You’re the most wonderful woman I know - beautiful, funny, clever, loving, honest, understanding and a fantastic wife and mother. Every day I feel grateful to have you in my life and I truly hope I make you feel loved and appreciated. Together we make a brilliant team - the future never scares me, because I know whatever happens you’ll be there, by my side.

To me, you are perfect; I love you now, always and forever.

A Plugin-Free Web

| Comments

It’s almost unheard of for me to complement something that Microsoft are doing - especially when it comes to Internet Explorer - but I’m 100% behind a plugin-free web:

John Hrvatin from the Internet Explorer team:

The transition to a plug-in free Web is happening today. Any site that uses plug-ins needs to understand what their customers experience when browsing plug-in free. Lots of Web browsing today happens on devices that simply don’t support plug-ins. Even browsers that do support plug-ins offer many ways to run plug-in free.

Metro style IE runs plug-in free to improve battery life as well as security, reliability, and privacy for consumers.

How long until Google joins the party?

Frequently friends and acquaintances will talk to me about iOS/Android (being an iOS developer) and one of the things they’ll very often say is “yeah, but iOS can’t run Flash,” as if that’s a bad thing! Banning Flash from the platform is one of the things that makes me really glad I own iOS devices and that they’ve such a large market share. Many websites that use Flash are being forced to redevelop into open and standards-compliant HTML & JS so that they can capture the mobile audience.

Flash is the most common browser plugin, and I loathe it. I block it on all my computers and only use it where I absolutely have to. If a shopping website forces me to use Flash to shop there then I simply don’t shop there. And with HTML5 Video/Audio and the speed of JavaScript in todays modern browsers (even the latest Internet Explorers!) there’s less and less justification for websites to use Flash (or worse: Silverlight! I’m looking at you, LoveFilm).

I’m not the only person who hates Flash, just look at all the plugins to disable it!

Why Plugins Suck

There’s many reasons, but mostly it comes down to non-compatibility, performance, security and user experience.

Compatibility

For a long time there was no Flash player for Linux. Then there was no Flash player for 64-bit operating systems. There’s no Flash for iOS. My Blu-ray player can’t run Flash. Apparently my Tivo does run Flash, but it’s god-awful.

Happy New Year 2012

| Comments

How’s your year going so far? Mine’s going really well. Xander’s walking well and he’s getting closer to speech every day which is fascinating and exciting to watch, my health has improved massively over last year and I’m really enjoying work.

This year I’m making an effort to do the things I’ve always meant to do as a programmer; and playing with lots of new (to me) tech in the process! I intend to cover a few of these topics in the coming weeks/months, but here’s a summary:

Vim

I’ve started using Vim as my main editor (or more specifically MacVim with the Janus vim distribution) and I’m loving it. It’s a relatively steep learning curve, but you don’t have to jump in at the deep end - just start with i to enter insert mode, use it like a normal editor, and then to save press <Esc> followed by :wq<Enter> to save and exit (drop the q if you don’t want to exit). Slowly start learning new things and forcing yourself to start using normal mode (where you type commands like :wq) and as you use more, you’ll want to use more. Once you’ve mastered the whole count-verb-modifier-noun grammar of vim you’ll be using it for everything and wondering how you ever managed without it!

Node.js

Okay, so I’ve been playing with this for a while, but I’m using it for more and more stuff now - pretty much anything that needs scripting I now do in JavaScript, or more specifically…

CoffeeScript

CoffeeScript, which is bloody brilliant - especially if you have a strong understanding of how the underlying JavaScript functions. This isn’t new either, but I’m now using it for ALL my JavaScript programming

Underscore.js

Underscore.js is a light library of helpful JavaScript functions for working with objects, arrays, collections and other such things in a functional programming way without extending the native objects. jQuery/Mootools use $ for working with DOM nodes, Underscore uses _ for dealing with everything else.

Backbone.js

Backbone.js extends Underscore.js and is a great way of keeping the code of your RIAs organised. It’s very flexible and can fit to many different programming methodologies, but I use it in a M-VC (Model, ViewController) manner not dissimilar to iOS. Event are emitted from models when they’re added, changed or deleted; hooking into these events allows your app to always display consistent information without the need for lots of hard-coded callbacks.

jQuery

It seems everybody uses jQuery, and has done since its inception. I refused to jump on the band-wagon and I’m glad I did - I coded everything in JavaScript from scratch using native methods and help from articles across the web (especially sites such as QuirksMode) and now have a very good understanding of how different parts of a modern web browser piece together and the faster/slower ways to go about doing things.

However, jQuery is a lot faster than it used to be, as are modern web browsers, so my concerns are much less valid. It reduces programming time significantly and adds flexibility so I now use it (or Zepto.js) in a lot of my projects and I really like it - it doesn’t take long to learn and master, and it improves the speed of Backbone development considerably.

Git

Git, as you should know, is a brilliant version control software. I’ve been using SVN for years but have had the itch to switch for ages, so with some new projects that I’ve been working on (using the above technologies) I decided to switch to using git where possible. It’s brilliant - lightening fast and so flexible. The lack of the old /trunk/, /branches/, /tags/ layout makes me happy too - trying to convince employees to use svn switch was very hard, but with git they’ve got no choice but to do it the right way! I’m using gitolite for our internal (private) hosting, and …

Open Sourcing

… I’ve started Open Sourcing some stuff I’m working on to GitHub. First is my ec2-prune-snapshots script for automatically deleting sensibly old EBS snapshots on AWS, but I intend to release much more in the coming year, and possibly even retro-actively releasing some older software, such as MythPyWii which currently sits on Google Code.

What Are You Using?

If you’re using some cool technology for web/mobile application development that you think I might enjoy experimenting with then please let me know in the cooments!

Multiple Asynchronous Callbacks

| Comments

When programming in JavaScript (or CoffeeScript) you sometimes face a situation where you need to complete multiple independant asynchronous methods before continuing. This situation crops up in web browsers but its much more common when writing server-side JavaScript, e.g. with Node.js - for example you might need to fetch from a database, fetch from a KVS, read a file and perform a remote HTTP request before outputting the compiled information to the end user.

One method of solving this issue is to chain the asynchronous calls, however this means that they’re run one after the other (serially) - and thus it will take longer to complete them. A better way would be to run them in parallel and have something track their completion. This is exactly what my very simple AsyncBatch class does:

.coffee.jsAsyncBatch class, triggers event once all wrapped callbacks complete
1
2
3
4
5
6
7
8
9
10
11
class AsyncBatch extends EventEmitter
  constructor: ->
    @_complete = {}
    @_scheduled = {}

  wrap: (name,cb) ->
    @_scheduled[name] = true
    return =>
      @_complete[name] = cb.apply @, arguments
      if Object.keys(@_complete).length == Object.keys(@_scheduled).length
        @emit 'done', @_complete

To use AsyncBatch, just do the following

.coffee.jsHow to use AsyncBatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
###
Create a new AsyncBatch instance
###
batch = new AsyncBatch

###
Wrap your callbacks with batch.wrap and a name
The name is used to store the result returned by your callback
(Don't forget to return the result you're interested in!)
###
delay 50, batch.wrap 'timer', ->
  return "Timer complete"

###
Add a completion handler that accepts `results` as a parameter.
  `results` is a JS object where the keys are the callback names 
  from above and the values are the return values of the
  callbacks.
###
batch.on 'done', (results) ->
  console.log "Batch complete, timer result: #{results.timer}"

NOTE: If your asynchronous method accepts both a success and failure callback then simply wrap both individually but ensure you use the same name for both.

NOTE: Other than the case in the previous NOTE, all callbacks should have different names.

A full example (including a stub EventEmitter implementation) follows:

CoffeeScript: JavaScript, but Clearer

| Comments

I really like CoffeeScript. I really like JavaScript. I’m trying to get into the habit of writing more CoffeeScript since, I think, it allows me to express myself clearer and more concisely, leading to shorter code and (hopefully) less mistakes/bugs. It also makes jumping back into code a month later a much simpler affair since reading the code is so much easier.

The following JavaScript creates a new closure inside each iteration of a loop to store the value of the loop variable i into the closure’s local variable j so that we don’t just console.log(10) 10 times. Though this example is trivial it represents a common method for solving closure related issues in asynchronous code.

JavaScript closure required for correct output
1
2
3
4
5
6
7
8
for (var i = 0; i < 10; i++) {
  (function(){
    var j = i;
    delay(0, function(){
      console.log(j);
    });
  })();
}

The following CoffeeScript does exactly the same thing, you can see the translation line by line from the JavaScript. However once you’ve learnt the syntax you can much more clearly see what is going on with the CoffeeScript than in the verbose and parenthesis-heavy JavaScript above.

.coffee.jsCoffeeScript to do the same thing
1
2
3
4
5
for i in [0..10]
  do ->
    j = i
    delay 0, ->
      console.log j

As a bonus,