February + March review

It’s already April! How did that happen? Busy busy busy. I neglected to do an update for February but hopefully I can kind of remember what happened. February isn’t a real month anyway. Need at least 30 days to be a real month I think. Pretty sure.

Update on the wedding plans: we’ve booked the venue for February next year! We started this in Feb and got the forms signed and deposit paid in March, so that’s the main thing that happened since the last update. We’ve chosen and booked a photographer too, both for the pre-wedding photos in Singapore and the actual day. We met with the guy and really like his photos and approach, so I think we made the right choice.

As for the PR application, I have an appointment to submit the documents next week! I still have a few pages to print / photocopy but it’s 90% there. It’s been a long process getting all the documents – it’s nearly 40 pages in total. Fingers crossed they accept my form and hopefully in 4-6 months I’ll hear back from them. I don’t think the wait will be too bad; it’ll be a relief just to finally submit the application.

In other news, we have a trip to the UK coming up in July! Woohoo! We’re there for 2 weeks so it’ll be our longest holiday yet. We’ll be busy towards the end of the year with the wedding and my family are coming over for that, so we thought why not take a long holiday in the middle of the year instead? There’ll be loads of time to travel around so we have a lot of options for what to do while we’re there. It’s going to be awesome. Brin even got a new camera for it.

Plans for April? Well, besides the PR application there’s some more wedding tasks: we’re meeting with a videographer and planning to book a pre-wedding photographer for the UK trip. I need to start sourcing for my suit and we’re going to work on the guestlist. I’d also like to get a website up where our guests can go for info. I’m not sure what it’ll look like yet, but I do want one of those new .wedding domains. We’ll see how that goes.

Mike

 

January review

Hello blog! So one of my resolutions this year was to plan better, and one of the ways I thought of doing this was to review each month as they go by. First month down, eleven to go. So let’s look back at January.

Wedding-wise, we’ve been making progress. We have a draft guestlist, venue shortlist, prices for dress rental and photography. We’ve visited quite a few venues and although we haven’t actually booked anywhere yet, we have 2 or 3 pretty good options. All our research and budget info is organized on Google docs and shared so it’s always there for us to refer to. Next month I hope to get the venue booked, and everything after that should fall into place. Anyway, I’m glad we’re starting early!

My PR application is going a bit slower than expected, since I’m having trouble getting some of the documents I need. Now there’s only 2 to go so I hope to have everything I need within the next 2 weeks, and maybe book an appointment after that to actually submit the application. I’m hoping I don’t have to wait too long for the appointment. We’ll see!

Work is going well. I have a pretty difficult project on at the moment, but my team are supportive and I’m just glad to be working on challenging stuff.

I set up a goal on Goodreads to read 25 books. So far I’ve read 1 so I’m a bit behind. I really liked the first book I read (Defenders by Will McIntosh) but I’m struggling with Ancillary Justice by Ann Leckie. The latter has amazing reviews so I’m sure it’s great, it’s just taking me a while to get into it. Ah well. I’ll try and catch up this week.

One of my new year’s goals looks set to be completed in the next 2 weeks though! I’ve booked a trip to Sabah with Brin and her family, to meet more of her family over there. I’m pretty excited because although we’ve travelled around Southeast Asia a bit, it’ll be different meeting up with locals (family too) and seeing how they live. We’re going for 4 nights. I hope to book our next UK trip this month too, probably the last before our wedding. Already looking forward to going back again.

Other than that, I’ve been following an exercise/diet plan fairly well and feeling pretty good. There’s a gym room where I live and the stadium down the road, so there’s really no excuse not to. Planning to keep up the diet for a couple more weeks and then step up the weight training mid-Feb.

Only one more week until Chinese New Year and a 4-day weekend. Yay!

2015 in review

2015 was my second full year in Singapore, and again a year of many changes, but somewhat slower changes compared with recent years. I changed jobs and moved house for the third time in as many years, but now I’m very happy with / proud of both: I can see myself in this job for several years, and will probably remain in my flat until I move in with Brin. After a hectic couple of years, I finally feel like I’m as settled as I was before I left for Singapore.

I left Perx and joined GrabTaxi in June, in a year of massive growth for the latter. It is challenging and I’m frequently out of my comfort zone, but I’m learning more than I have in years. They’re one of the biggest tech companies in the region, have some incredibly talented engineers, and in my opinion are pretty great to work for. It was a conscious decision to join a bigger company after a string of start-ups, as I really wanted (and require) a more stable job. Changing jobs takes a lot of time and effort, so fingers crossed I won’t have that to worry about in 2016.

I learned several new things. I successfully brewed beer for the first time, thanks to the kit that Brin got me for Christmas. This took a lot of preparation – I had to buy a new fridge especially for it – but it was fun and very rewarding. Tech-wise, I’ve been learning and am now using Go professionally. I got a Pebble watch for my birthday and dabbled with their development kit, which was a pleasure. I’ve been migrating some of my websites (including this blog) off the cloud and onto a mini PC hosted at home (not sure why – I guess I like having my stuff where I can see it). Brin and I have taken to the escape room phenomenon and it’s become one of our new favourite hobbies.

But the biggest event of 2015 was the most personal one, as Brin and I got engaged! We’re planning to get married at the start of 2017 and I can’t wait. The preparations have already begun and there’s going to be a lot of this in 2016. The ring was custom-made at JannPaul and I’d definitely recommend them.

engagement

Other personal things: I’m glad I got to visit the UK twice in 2015, including being home for Christmas with my family. I’d missed that a lot. I got a new pair of glasses and finally visited the dentist here in Singapore, which lifted some weight off. Health-wise I can’t complain, which I’m grateful for.

Now to look forward to the new year: what can I do better?

Firstly, I need to prioritise better. I (and Brin) have a lot of things to plan for in 2016, so properly planning and organising our time is going to be crucial both for completing the things we need to and not getting burnt out while doing so. I get easily distracted with side-projects and find it hard not to go ‘all-in’ when I set my mind to something: I’ll focus intensely on that one thing for weeks or months. Then, when I do step away from it, I’m overwhelmed by everything else that’s been going on. I need to remember to balance things, to take a step back and reflect on the bigger picture. One thing I intend to do here is to blog more, perhaps a monthly review or something. (Note: I’ve switched my blog to WordPress to help with this – it makes editing a lot easier than the custom-built blog I had before).

I learned last year that I can always count on my friends, and sometimes perhaps I underestimate this. Although I have many friends that I don’t keep in touch with regularly, they’re always there and hanging out with them is no less fun if it’s twice a year than twice a week. Meeting up with friends for my birthday and at Christmas proved this.

My goals for 2016 are somewhat obvious, but not easy, so achieving them would definitely make 2016 a good year for me. Planning the wedding is the main one, of course. Secondly, I want to gain PR status in Singapore: a requirement for buying a house here (even though Brin is Singaporean), and find a house together for 2017. Another goal for me is visiting Sabah, where many of Brin’s family lives, which I hope to finally accomplish in 2016. Then I have some general goals: travel more, write again (it’s about time I had another story published), and not start so many side-projects, although I still want to make smaller contributions to open-source. Those are the main ones anyway; I hope there are many (good) unexpected things to do too!

Happy new year!

Thoughts on Go

Traditionally I’m a pretty late adopter of new trends, and Go has been out for something like 6 years now, so I figured it would be a good time to try it. I’ve been learning it for about 2 months; I’ve done dozens of Codility exercises, written a WebSocket server and a statusbar daemon, so I think I’ve given it a good go. My experience has been generally positive and I’ll definitely use it in future.

The Go FAQ is pretty clear about the objectives for the language: it’s supposed to be easy to program in, but also efficient and (type) safe. It’s obvious from spending some time with the language that it’s met these goals. Make no mistake, Go is not a low level language, although it produces similar effects. It has a simple, lightweight type system, built-in support for concurrency and garbage collection. You can even import packages straight from GitHub. It might be a compiled language with C-like syntax, but it’s easily accessible to those with little or no experience with C or C++.

The language’s syntax has intentionally been kept simple and clean, and while I feel that this does limit expressiveness (more on this later), it undoubtedly has advantages in making the language easy to learn. Generally I’m happy with the features that Go does include, with one exception: I strongly dislike the error handling.

Go takes the approach to allow functions to return multiple values, and the convention is to return an error as one of the return values. There’s an error type that makes it easy to handle these kind of errors in a consistent way. But the reason I dislike errors as return values is that error checking should not be optional. In my opinion, if it’s possible to call your function without checking the error, you’re asking for trouble. Of course, you can argue that you/your employees are disciplined enough to check every error, but why take the chance? The fact that errcheck – errcheck checks that you checked errors even exists is a sign of a language flaw, in my opinion.

I much prefer try/catch and the like for handling errors across function/package boundaries. Go does actually have panic/recover to provide a similar mechanism, but it generally seems less preferable to returning error values. They explain their case here, but I still strongly disagree. Ah well.

Go’s syntax makes it easy for developers to pick up, and the lack of complexity means that once you’ve grasped the syntax, it’s not too difficult to understand other Go code. This is definitely good from a developer’s perspective. The toolchain is intuitive and easy to use; I don’t feel like I need an IDE to set up or build my programs. The compiler is strict but not annoyingly so, and fixing the compile errors feels quite satisfying: your program probably works afterwards. Generally, it’s a language that doesn’t get in your way, and it’s not difficult to focus on writing code.

However, the language trades simplicity for expressiveness, and I often lament that I could have written the same thing in far less code in Ruby. The benefit is that my programs are compiled (finally I can write programs that load quickly!) and type safe. They also use less memory and are faster at runtime, but I think this point is overrated. It takes a very specific class of problems to benefit from faster runtime performance; if your code is heavily IO/database bound or relies on a 3rd party API, the speedup from a compiled program isn’t going to help much. I think slow runtime code should not be the primary reason to use a different language, and should be solved by proper code optimization/architecture instead.

Still, there are definitely problems that Go works very well for. For example, web services where low latency is critical (especially those that are CPU intensive) are an excellent use case. Command-line programs where fast startup time is important. Background jobs that are CPU-bound can be shipped off to Go workers for faster processing. These tasks make Go an excellent tool to have. I just wouldn’t use it for a traditional website, where the bottleneck is almost always the database.

For large teams, Go’s simplicity and ease of adoption is extremely attractive. It enforces some code quality rules at compile time (eg. removing unused variables), and code style via other tools (eg. go fmt, go vet and golint), and is of course type safe. There is a well-defined, enforceable, ‘right’ way to do a lot of things in Go, and I think this definitely helps with maintainability. I just wonder if this takes some of the fun out of it, though. One of the main reasons I enjoy programming (and loved Perl for many years) is that I can be creative and write elegant solutions that read well in the context of the problem. Code efficiency is not the only factor; programmer productivity is, too, and Go feels like it was primarily designed to solve computer problems, not human ones.

Then again, I’m not planning to give up Ruby any time soon, and there’s definitely room for Go in my toolbox. And Go is still young; Perl had been out for 15 years before I started learning it. So it’ll be interesting to see how it develops.

-Mike

Docker: first impressions

I’ve been wanting to try Docker ever since I saw a talk about it at Red Dot Ruby Conf. The idea of being able to build a container in development and ship it to staging, then production without any changes is extremely enticing, although I admit to being a little sceptical. Now I’ve implemented a Docker deployment process for the first time with one of my projects. Is Docker the holy grail of cloud deployment, or is it all just hype? Well, probably a bit of both.

Baby steps

Docker is really, ridiculously easy to get started with. If you’ve read about it before, you’ve probably seen basic examples like this:

$ sudo apt-get -y install docker.io
$ sudo docker run -t -i ubuntu:14.04 /bin/bash

That’ll get you a shell on a Docker container. Simple. Not very useful, but a friendly starting point.

Docker concepts

Docker revolves around two main concepts: images and containers. Images are just like VM images: they’re things you can copy, download, share and run. Containers are running instances of images. You can start, stop and save them, again much like VMs. But unlike VM images, they’re much smaller and lightweight, and generally more portable.

The basic commands are:

  • docker run to start a container from an image
  • docker build to build an image from a Dockerfile (more on that later)
  • docker ps to see running containers
  • docker rm to remove/stop running containers

There’s also docker push and docker pull to push and pull images to the Docker registry (or your own registry).

Running a Rails application

My project runs on Rails, so my Docker container would have to support Rails applications. Fortunately, there’s a pre-built image for this using Nginx and Passenger: https://github.com/phusion/passenger-docker. This makes things easy to get started, but it wouldn’t be too difficult to switch to a different webserver. There’s many similar base images to choose from, but this was the one I went with.

In order to use this image for your own application, you need to make a few changes as documented in the readme. Namely:

  • Copy your application into the image
  • Configure nginx
  • Preserve environment variables for nginx

I made the additional step of pulling my project onto the image using Git, which needed me to first set up ssh.

You can change the base image by one of two ways:

  • Make changes directly to the container and save them using docker commit
  • Build a new image using a Dockerfile

I opted for the second way, because having the steps in the Dockerfile acts as documentation and makes the process completely repeatable and transparent. However, I don’t think there’s any harm in using docker commit either. Generally the argument against just modifying a VM image is because it then makes it difficult to port to other hosts or operating system, but that doesn’t really apply here: Docker images run on Docker, which can run on practically any hardware and OS.

Here’s my complete but slightly censored Dockerfile:

FROM phusion/passenger-ruby21:0.9.14

ENV HOME /root

# Use baseimage-docker's init process.
CMD ["/sbin/my_init"]

# Install git
RUN apt-get -y install git && \
# Clean up APT when done.
    apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Add my ssh key
ADD id_mikec /tmp/id_mikec
ADD id_docker /home/app/.ssh/id_docker
ADD ssh_config /home/app/.ssh/config
ADD sudoers /etc/sudoers
RUN cat /tmp/id_mikec >> /root/.ssh/authorized_keys && \
    rm -f /tmp/id_mikec && \
    chmod 600 /home/app/.ssh/config /home/app/.ssh/id_docker && \
    chown -R app:app /home/app/.ssh && \
    adduser app sudo && \
    mkdir -p /srv && \
    chown app /srv && \
    rm -f /etc/nginx/sites-enabled/default /etc/service/nginx/down

# Switch to app user
USER app
ENV HOME /home/app

# Do clone
RUN mkdir -p /srv/myapp && \
    git clone git@<git-server>:mikec/myapp /srv/myapp && \
    cd /srv/myapp && \
    bundle install && \
    mkdir -p /srv/myapp/tmp/cache

USER root
ADD nginx_env.conf /etc/nginx/main.d/nginx_env.conf
ADD set_passenger_env.sh /etc/my_init.d/01_set_passenger_env.sh
ADD myapp.conf /etc/nginx/sites-enabled/myapp.conf

# Update checkout
USER app
ADD VERSION /tmp/VERSION
RUN cd /srv/myapp && git pull && bundle install
USER root

Building the image

You’ll notice above that the Dockerfile does a git clone and then another git pull. This is because Docker caches each command; if the command doesn’t change, then it doesn’t run the command the next time it builds the image. To force Docker to invalidate its cache, I use a VERSION file that I modify locally before running docker build. I’ve written a simple build script to help with this task (I put it in bin/build):

#!/bin/bash
date +%s > docker/VERSION
git add docker/VERSION
git commit -m 'Build release'
git push
sudo docker build -t mcartmell/myapp docker
sudo docker push mcartmell/myapp

Building the image

This was the trickiest part for me. I want to ensure my image works on different environments (eg. staging and production) without any changes, because I think that’s one of the major selling points of Docker. But keeping your image agnostic to any environment settings is difficult.

I accomplished this by creating an environment file on the host server that stores application secrets and database settings. I know this creates a dependency between the container and the host, but that’s not really avoidable, and I see this environment file more like ‘infrastructure settings’ than configuration specific to the application. Plus, it’s similar to how dotenv works in typical Rails deployments, so I was satisfied.

The docker run command looks like this:

$ sudo docker run -p 80:80 --name="myapp" -d --env-file /etc/myapp/docker_env mcartmell/myapp

Note the --env-file argument that allows you to specify a file of environment variables rather than passing them in on the command-line.

This environment file, when used with the tweak to nginx to allow it to pass through environment variables, worked nicely for me. One slight problem was that Passenger itself doesn’t honor the RAILS_ENV environment variable – it has to be set explicitly in the config file. Since I’m only passing in the environment at runtime, we can’t set this in the config file in the image, so I had to create an init file to set the passenger_app_env.

This extra file (set_passenger_env.sh referenced above) was pretty simple:

#!/bin/bash
echo "passenger_app_env $PASSENGER_APP_ENV;" > /etc/nginx/conf.d/passenger_env.conf

Not ideal, but I’m OK with it for now.

Deploying the Docker image

I was looking for Docker deployment tools, but there’s currently not a great deal of choice out there. The closest thing I found was NewRelic’s Centurion, but I ended up not trying this and rolling my own deploy script with sshkit instead:

#!/usr/bin/env ruby
require 'sshkit'
require 'sshkit/dsl'

on ['mikec@server'], in: :sequence, wait: 5 do
  execute 'sudo docker pull mcartmell/myapp'
  execute 'sudo docker rm -f myapp', raise_on_non_zero_exit: false
  execute 'sudo docker run -p 80:80 --name="myapp" -d --env-file /etc/myapp/docker_env mcartmell/myapp'
end

All this does is pull the new image, stop the running container and run a new one. A production environment would ideally be behind a load-balancer to do a rolling deployment, but as it only takes a second to stop and start the container, this way suits me for now. I’m opting to start simple and expand this script as needed.

Pros and Cons

Pros:

  • Very low-risk deployment: fresh container every time
  • Images can run anywhere: local, cloud VM, dedicated servers
  • Many existing images to use
  • Lightweight and easy to install
  • Rolls server configuration and application deployment into one process

Cons:

  • Slow build and push. A push with no changes takes me 2 minutes. Compared with a regular git push / git pull for your code, this is slow, but when you consider it’s pushing an entire standalone runtime environment, it’s actually pretty fast.
  • Complex deployment process. It’s not too complicated, but certainly more difficult to grasp than just git.
  • Lack of drop-in deployment tools
  • Even with a base image, still a lot of manual effort to get a working container

Overall it’s been a good experience, and I’ll probably be using Docker in production. It does slow down the deployment process, but the peace of mind you get from knowing that the exact container has been working in development and staging is definitely worth it, in my opinion. And the fact that I can run my app anywhere (assuming there’s a database and environment file) is a major bonus. No more having different configuration scripts for Vagrant in development, Amazon cloud VMs for staging and dedicated servers in production: just set them up to run Docker and push your containers.

Automated Rails testing with Capybara and PhantomJS

Capybara is one of those tools that sounds great but is often frustrating. The claims of ‘no setup’ and ‘intuitive API’ make it sound like automating your browser testing is going to be a simple task. Unfortunately, the nature of these full-stack tests mean they’re often very tricky to get working reliably, and this has always put me off before. Testing should save you time, not create extra work.

This weekend, starting on a new test suite, I decided to go about really getting a solid Capybara setup, and get a complex test passing every time without anysleep hacks. Here’s how I did it.

1. Prerequisites

I used the following gems (add them to your Gemfile):

  • rspec-rails
  • capybara
  • database_cleaner
  • poltergeist
  • factory_girl_rails

You might also want to install phantomjs with your package manager if poltergeist doesn’t install first time.

Install with bundle install and then rails g rspec:install.

2. Test authentication

One of the first problems is how to get your ‘logged-in’ tests working. Devise’s regular helpers don’t work with Capybara (it doesn’t have access to the Rails request), so I used Warden.test_mode! instead:

In spec/rails_helper.rb:

include Warden::Test::Helpers
Warden.test_mode!

RSpec.configure do |config|
  # Fast login for tests that specify 'login: true'
  config.before(:each, login: true) do
    @user = FactoryGirl.create(:user)
    login_as(@user, scope: :user)
  end
end

This creates a user with FactoryGirl and logs them in before every test that has login: true, eg:

describe 'My test', login: true, js: true do

3. Database cleaner

Since Capybara runs in a separate thread, and your tests run within a database transaction, the Capybara browser won’t see your database changes without some extra effort. My solution was to disable transactional fixtures and configure database_cleaner as described in this post.

In spec/support/database_cleaner.rb:

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

Basically, this says that for js tests, don’t use transactions but truncate the database tables instead.

4. Poltergeist

Poltergeist is a Capybara driver for PhantomJS, a nice tool that lets you automate JS testing without a browser.

This doesn’t take much configuration, but if you want to enable remote debugging (so you can attach a javascript console to your tests), you can use the following helper.

In spec/support/capybara.rb:

require 'capybara/rspec'
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist_debug do |app|
  Capybara::Poltergeist::Driver.new(app, inspector: true, debug: true)
end
Capybara.javascript_driver = :poltergeist_debug
Capybara.default_wait_time = 5

5. Waiting for asynchronous JS events

Capybara gives you many tools to help avoid timing issues, but sometimes they’re still not enough. Capybara 2.0 removed the wait_until feature, so you have to find another way to replicate this feature if Capybara’s built-in waiting isn’t working for you. After reading this post, I adapted their become_truematcher.

In spec/support/wait_steps.rb:

require "timeout"

RSpec::Matchers.define :become_true do
  match do |block|
    begin
      Timeout.timeout(Capybara.default_wait_time) do
        until value = block.call
          sleep 0.1
        end
        value
      end
    rescue TimeoutError
      false
    end
  end

  def supports_block_expectations?
    true
  end
end

This means you can do things like:

expect{page.evaluate_script('someJSFunction()')}.to become_true

and the above code will wait until the JavaScript function returns true (eg. to indicate page readyness).

6. Troubleshooting non-determinism

If you’re still having trouble with non-deterministic tests:

7. The full helper file

This is my spec/rails_helper.rb in full:

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

# Add additional requires below this line. Rails is not loaded until this point!
require 'factory_girl_rails'
include Warden::Test::Helpers
Warden.test_mode!

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.include FactoryGirl::Syntax::Methods
  config.infer_spec_type_from_file_location!

  # Fast login for tests that specify 'login: true'
  config.before(:each, login: true) do
    @user = FactoryGirl.create(:user)
    login_as(@user, scope: :user)
  end

  # Seed the database first
  config.before(:suite) do
    Rails.application.load_seed
  end
end

Hope someone else finds it useful.

Mike

Making a game with Phaser

Today I felt like making a game, so I learnt about Phaser and set myself the task/challenge of recreating a simple game from my childhood. Phaser is incredibly fun and easy to get started, I’d recommend giving it a go!

The game I chose was Tanx.

I started with the excellent Phaser tutorial and converted it to CoffeeScript. It’s perfectly fine to use CoffeeScript with Phaser, or I guess any other language that compiles to JavaScript.

It’s very rough and I only spent a few hours on it, but it gives you an idea of what you can make with this framework, even without any prior knowledge!

Instructions:

Try to shoot the other player by adjusting the angle and power. From the left, try an angle of about -30. From the right, try an angle of about 210.

Keys:

UP/DOWN: adjust angle
A/Z: adjust power
LEFT/RIGHT: pan screen
SPACE: fire / start new game

Full source code:

GAME_WIDTH = 1200

currentAngle = 0
currentPower = 500
maxPower = 600

cursors = null
current_player = null
font = null
win_message = null
tanks = null

firing = false

game_over = false

toRad = (angle) ->
  angle * Math.PI / 180

loadFonts = =>
  @angle = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1
  @power = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1

bulletHit = (body, shapeA, shapeB, equation) ->
  firing = false
  this.kill()
  if body.sprite.parent == tanks
    game_over = true
    win = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1
    win.text = current_player.name + ' wins!'
    win_message = game.add.image 60, 300, win
    win_message.fixedToCamera = true
    win_message.cameraOffset.x = 60
  else
    nextTurn()

changeAngle = (diff) ->
  setAngle(currentAngle + diff)

setAngle = (angle) =>
  currentAngle = angle
  @angle.text = 'angle: ' + currentAngle

changePower = (diff) ->
  setPower(currentPower + diff)

setPower = (power) =>
  currentPower = power
  @power.text = 'power: ' + currentPower

resetAngleAndPower = ->
  setAngle 0
  setPower 200

nextTurn = ->
  resetAngleAndPower()
  current_player = if current_player == @player
    setAngle 180
    @player2
  else
    setAngle 0
    @player
  resetCamera()

resetCamera = ->
  game.camera.target = current_player

resetGame = ->
  game_over = false
  current_player = @player
  resetCamera()
  resetAngleAndPower()
  win_message.destroy()

fireBullet = =>
  unless firing
    # create a bullet
    angle = currentAngle
    power = currentPower
    # calculate velocity
    x_velocity = Math.cos(toRad(angle)) * power
    y_velocity = Math.sin(toRad(angle)) * power
    cp = current_player
    #offset to avoid shooting self
    offset_x = if angle > 90 || angle < -90
      -32
    else
      32

    # create the sprite and set it going
    bullet = game.add.sprite cp.x + offset_x, cp.y, 'bullet'
    game.physics.p2.enable bullet
    bullet.body.velocity.x = x_velocity
    bullet.body.velocity.y = y_velocity
    bullet.body.onBeginContact.add bulletHit, bullet
    game.camera.follow bullet
    firing = true

@preload = ->
  game.load.image 'sky', '/games/assets/sky.png'
  game.load.image 'ground', '/games/assets/platform.png'
  game.load.image 'bullet', '/games/assets/ball.gif'
  game.load.spritesheet 'dude', '/games/assets/dude.png', 32, 48
  game.load.image 'knightHawks', '/games/assets/fonts/KNIGHT3.png'

@create = =>
  game.world.setBounds 0, 0, GAME_WIDTH, 600

  game.physics.startSystem Phaser.Physics.P2JS
  game.physics.p2.gravity.y = 100
  game.physics.p2.defaultRestitution = 0.9
  game.physics.p2.setImpactEvents true

  sky = game.add.tileSprite 0, 0, 2000, 600, 'sky'

  # create the ground sprite and set to static
  @ground = game.add.sprite 0, game.world.height - 48, 'ground'
  @ground.scale.setTo 6,3

  game.physics.p2.enable @ground
  @ground.body.static = true

  # create the 'tanks'
  tanks = game.add.group()
  @player = tanks.create 32, game.world.height - 150, 'dude'
  @player.frame = 5
  @player.name = 'Player 1'
  @player2 = tanks.create GAME_WIDTH - 120, game.world.height - 150, 'dude'
  @player2.name = 'Player 2'

  # angle / power text
  loadFonts()

  @ang = game.add.image 30, 30, @angle
  ang.fixedToCamera = true
  ang.cameraOffset.x = 30

  pow = game.add.image 30, 60, @power
  pow.fixedToCamera = true
  pow.cameraOffset.x = 30

  setPower currentPower
  setAngle currentAngle

  # enable physics!
  tanks.forEach (thing) ->
    game.physics.p2.enable(thing)
    thing.body.gravity.y = 100

  # set first player 
  current_player = @player

  game.physics.p2.setImpactEvents true

  cursors = game.input.keyboard.createCursorKeys()
  game.input.keyboard.addKeyCapture Phaser.Keyboard.SPACEBAR

@update = ->
  if game_over
    if game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)
      resetGame()
  else
    if cursors.right.isDown
      game.camera.target = null
      game.camera.x += 8 
    if cursors.left.isDown
      game.camera.target = null
      game.camera.x -= 8 
    if cursors.up.isDown
      changeAngle -1
    if cursors.down.isDown
      changeAngle 1
    if game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)
      fireBullet()
    if game.input.keyboard.isDown(Phaser.Keyboard.A)
      changePower 1
    if game.input.keyboard.isDown(Phaser.Keyboard.Z)
      changePower -1
@game = game = new Phaser.Game(800, 600, Phaser.CANVAS, 'tanks', { preload: preload, create: create, update: update })

Variable scope in Ruby

One big difference between Perl and Ruby is that Ruby has no lexical variables. This confuses me when programming Ruby, because I’m used to thinking ifwill create a new scope. It doesn’t. Variables defined inside if will be available outside, because they belong to the method scope.

For example, in Ruby you can do this:

def foo
  if true
    x = 2
  end
  puts x
end

foo

This prints 2.

However, in Perl:

sub foo {
  if (1) {
    my $x = 2;
  }
  print $x;
}
foo();

You get the warning Use of uninitialized value $x in print at lexical_test.pl line 5..

This is OK. If anything, the Ruby version looks more convenient. But I prefer my variables to have as small a scope as possible, because it avoids mistakes like this:

def foo
  x = 1
  if true
    x = 2
  end
  puts x
end

foo # prints 2. what have you done to my x?

In Perl, we’d write it like this:

sub foo {
  my $x = 1;
  if (1) {
    my $x = 2;
  }
  print $x;
}
foo(); # prints 1

So how to avoid it in Ruby? Well, you could create a new method, or you can create a new block (eg. with a lambda or proc). This feels a bit weird though. Maybe a more Rubyish way is to use Object#tap, like so:

def foo
  x = 1
  2.tap do |x|
    puts x # 2
  end
  puts x # 1
end

That gets a bit unwieldy if you have multiple variables. But then, if you need more than 1 variable with the same name in your method, then it’s probably a sign that you should write a new method…

The Heartbleed bug

On reading about the Heartbleed bug bug, my first thoughts were:

  1. This sounds quite simple, is it really easy to spot?
  2. Why wasn’t this noticed during review?

The bug is in the Heartbeat Extension for TLS, as described in this draft. Interestingly, this document does actually highlight the importance of checking the payload length:

If payload_length is either shorter than expected and thus indicates padding in a HeartbeatResponse or exceeds the actual message length in any message type, an error Alert message using illegal_parameter as its AlertDescription MUST be sent in response

It also says ‘This document does not add any additional security considerations’, but I wouldn’t expect programming mistakes to be listed there anyway. So it looks like the initial draft is sound.

The actual commit that introduced the bug is online too; you can find it here. Now I don’t really know C, so I don’t think the bug is immediately obvious, even to competent programmers.

unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */

/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;

if (s->msg_callback)
        s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                &s->s3->rrec.data[0], s->s3->rrec.length,
                s, s->msg_callback_arg);

if (hbtype == TLS1_HB_REQUEST)
        {
        unsigned char *buffer, *bp;
        int r;

        /* Allocate memory for the response, size is 1 bytes
         * message type, plus 2 bytes payload length, plus
         * payload, plus padding
         */
        buffer = OPENSSL_malloc(1 + 2 + payload + padding);
        bp = buffer;

        /* Enter response type, length and copy payload */
        *bp++ = TLS1_HB_RESPONSE;
        s2n(payload, bp);
        memcpy(bp, pl, payload);

        r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);

However, I’d still expect C programmers to find it, given a decent review. And even without knowing C, it has issues:

  1. The payload length is stored in a variable called payload. This is stupid naming. A variable called payload should contain the payload.
  2. The payload is actually stored in pl and bp.
  3. I can’t see any reference/comment to checking the payload length as in the above draft.

It’s not obvious to spot; I’ve certainly missed things like this in the past. But it’s still poor coding, doesn’t stick to the original draft, and was inadequately reviewed.

10 Singlish phrases I would actually use in the UK

Possibly not everyone knows that English is an official language of Singapore (one of 4.) What’s more, there is an unofficial (and sometimes frowned upon) mini-language called Singlish, derived from bits of Hokkien, Teochew, Malay, English and Tamil.

Most of these words exist either to express something that does not have an English equivalent, or to say something more succinctly. Either way, it does come in handy, and it’s fun to use language that would be unacceptable or confusing back home.

So here’s a list of my 10 favourite Singlish words and phrases, some of which I’d probably use when I visit the UK:

1: Shiok

This is used to describe anything that feels good, especially when eating. That feeling you get when eating a really hot curry, almost painful but oh so nice?Super shiok.

2: Kiasu

This means ‘afraid to fail’, and is used to describe any overly competitive behaviour. Jumping the queue, pushing onto a train, panic buying are all forms of being kiasu.

3: Atas

This is like ‘posh’ in British English, or ‘snooty’.

4: Can

This is lazy, but I use it shamelessly. It is a very versatile word that can mean ‘you may do that’, ‘that is acceptable’, ‘that is indeed possible’ and more. As a question, Can? can mean ‘can I do this?’ or ‘will this work?’ or ‘do you want me to do this?’ Probably lots more examples too.

5: Kaypoh

Someone who is kaypoh is nosey; a busybody.

6: See how

This means ‘I will wait and see how things turn out’. It’s one of Brin’s favourite phrases, and I have stolen it.

7: Chope

OK, I’m not sure I’ll get to use this one in the UK, but it means to reserve/save a seat, especially with a tissue pack or an umbrella. Yeah. Kind of a specialist one.

8: Ulu

Great word. This means a place that is remote and maybe kind of weird for being so. Singapore is half the size of London, so being ‘remote’ is quite relative.

9: Got

Like can, this can be used as a question or in a statement. It can mean ‘you have” or ‘I have’ or ‘this place has’, or in question form can mean ‘do you have?’ “This place got ghost.” “Confirm got one.

10: Uncle

Though it will be wrong to do so, I will almost certainly use this in the UK. It’s used to address an older person, in certain types of shops, and /always/ cab drivers. Unless they’re younger (bro) or female (auntie). This is so natural now, it confuses me how I could communicate with taxi drivers in the UK before.“Uncle, got change for 50 anot?” “Get out.”

UK friends: you have been warned. Singaporeans: how am I doing? Are there any Singlish words I’m missing out on?