The stupidest thing I ever saw a developer do

So this story comes up quite a lot – this is the stupidest thing I ever saw a developer do. I need to paraphrase a little because it’s been many years, but in a nutshell we’d had a new guy start as a junior developer and he was working through bug tickets, with instruction to run solutions past another developer prior to checking them in. He was dealing with an issue where the backtrace read something like this:

undefined method `capitalize' for nil:NilClass (NoMethodError)

Which is a relatively simple exception to explain and is probably, in my experience, the most common backtrace a developer will ever see. It usually means that someone has not coded defensively, or that something has been coupled to something else in a non-obvious way and someone didn’t realise. You can easily achieve the error yourself:

my_hash = {}
my_hash[:key].capitalize

Anyway, after working on it for a few hours our developer came to me with his solution. Here is what he had done:

class NilClass
  def method_missing(method_sym, *arguments, &block)
    return
  end
end

For non-rubyists, here is a translation of what that bit of code does:

Let’s change the meaning of nothing, so that whenever someone tries to do something to nothing, we just do nothing.

I am not entirely proud of my reaction at the time, which was basically to laugh at the guy, tell pretty much everyone in the office about what he’d done, and then continue to tell the story for many years to come. To his credit, this “fix” had actually, to the untrained eye, fixed the problem because the software was now behaving as expected.

Evidently, the developer in question had, upon seeing the backtrace, Googled it. He had found a stackoverflow entry where someone else was having the same issue and some helpful user had submitted the NilClass monkey patch as a joke answer to the question. Other helpful users had up-voted this answer, which lead to our guy not identifying it as a joke.

I tried in vain to track down a link to this stackoverflow entry (it was many years ago) but to no avail.

Like I said, I tell this story quite a lot – the most recent time was earlier on today in fact, and it got me thinking. I worked through  the steps that this particular developer had taken:

  • He googled the error
  • He found a “solution”
  • Without understanding it, he stuck it in the codebase

And it dawned upon me that maybe I had been a little harsh on the guy, because that little trio of bullet points right there is one I have followed a whole bunch of times myself, especially when I was first getting started as a dev.

I never had a mentor, and regularly found myself being completely out of my depth and being asked to do things which I had no idea how to do. It was scary, it was stressful, and whilst being pushed in the deep end does make you very good very quickly (provided you swim) it can lead to you becoming overly reliant on the internet for solutions. You become adept at “skimming over documentation”. It’s bad practice.

If this story feels kind of familiar to you, then know that you are not alone – almost every programmer I have ever worked with has at some point engaged in “stackoverflow driven development” . Nowadays I always try to be aware of what I do not know – Taking time to properly understand what a solution means is not wasted time.

And if the guy who I laughed at ever reads this, please consider this an apology.

Ruby’s instance_exec method

instance_exec is a method you can use to change the “scope” of a block. One of the great advantages of doing this is that it can make your code more readable, particularly when writing a Domain Specific Language (DSL). So how does instance_exec work and why would you ever want to write a DSL?

instance_exec is pretty easy to demonstrate by way of a silly example. Let’s suppose you are running a Cattery. For anyone who doesn’t like silly examples, you can think of the cats as some kind of unmanaged resource (for example, a database connection) and the cattery as a pool of these resources (e.g. a database connection pool). Any cats that manage to escape the cattery can be considered to therefore be a memory leak that will harm your application and ultimately lead to sleepless nights and long days.

It might actually be easier on stress levels to just think of them as cats.

First, we define a simple class to represent a “cat”:

class Cat
  def speak!
    puts "meow!"
  end
end

and then another class to define the cattery itself, which internally stores an array of the cats currently in the cattery as well as providing an interface to add a new cat. Additionally, the cat should express itself by “speaking” after it is added to the cattery:

class Cattery
  def initialize
    @cats = []
  end

  def add_cat(cat)
    @cats << cat
    cat.speak!
  end
end

Let’s try it out:

cattery = Cattery.new
cattery.add_cat(Cat.new)

=> "meow!"

Lovely stuff.

Now imagine you discover that your cats keep escaping and you decide that the easiest way to stop this happening is to install a “door” on the cattery (assuming that the resident cats have not yet figured out how to open doors). So, you change your Cattery class accordingly by providing an interface to allow a door to be open and closed. You further alter your “add cat” method such that it will not allow a cat to be added unless the door is open:

class Cattery
  def initialize()
    @cats = []
    @door_open = false
  end

  def open_door
    @door_open = true
  end

  def close_door
    @door_open = false
  end

  def add_cat(cat)
    if @door_open
      @cats << cat
      cat.speak!
    else
      raise "Can't add a cat when the door is not open!"
    end
  end
end

Sweet. Now when you try adding a cat when the door is closed you get an error:

cattery.add_cat(Cat.new)
=> :in `add_cat': Can't add a cat when the door is not open! (RuntimeError)

cattery.open_door
cattery.add_cat(Cat.new)
=> "meow!"

Great! Nice and secure. only one problem… the developer who wrote that last piece of code forgot to close the door afterwards (doh!). How do we ensure that the door always gets closed properly after a cat is added?

Maybe you could use the begin/ensure (try/finally for non rubyists) syntax within the add_cat method? Well, if you go down that road then you’re breaking the single responsibility principle for that method – it’s called “Add cat” that’s all it should really be doing… but now it’s responsible for both adding the cat AND opening and closing the door. The method would also become coupled to the door interface which may cause future issues if we ever decide to change that interface or extract the door out into a class of its own. You might think that you could just remember to do a begin/ensure every time you add a cat:

begin
  cattery.open_door
  cattery.add_cat(Cat.new)
ensure
  cattery.close_door
end
=> "meow!"

But then you’re pretty much back in the boat you were originally, where you were relying on programmers to remember to close the door after themselves… only this time you have twice as much code!

At this point rubyists will start considering blocks. You might find yourself thinking along these lines :

* We could create a method to safely open the door and close the door afterwards, yielding to a block.
* We could remove the open/close methods on the cattery so people need to use that method to add a cat.

Such a method might look like this:

class Cattery
  ...

  def safely_open_door(&block)
    begin
      @door_open = true
      yield self
    ensure
      @door_open = false
    end
  end
 
  ...
end

Purrrfect. This would allow you to do the following:

cattery.safely_open_door do |this_cattery|
  cattery.add_cat(Cat.new)
  this_cattery.add_cat(Cat.new)
end

And you could stop right there – the solution works and the cats are safe. However, the code is not beautiful. We have multiple versions of the same variable floating around, both inside and outside of the block, which is confusing. It looks messy. Wouldn’t it be nicer if we could, just within the scope of the block, consider ourselves to be in the “cattery domain” where we could exclusively talk to the cattery without worrying about what’s going on outside of the block?

This is where instance_exec comes into play.

instance_exec changes the scope of the code within the block itself, and subsequently will change the result of calling “self” within it. In its current form, the block is scoped to the “main” object, which is why we are able to access the “cattery” variable.

What would be really nice is if this block were to be scoped to the cattery itself – any code within it would therefore be specific to the domain of dealing with a cattery. We can actually achieve this with one simple change to the code we have already:

class Cattery
  ...

  def safely_open_door(&block)
    begin
      @door_open = true
      instance_exec(&block)
    ensure
      @door_open = false
    end
  end
 
  ...
end

All we have changed is “yield” to “instance_exec”. The block will still be called (you can even pass additional arguments to the instance_exec method if you want to and they’ll be yielded to the block too). Making this small change allows us to finally write the code we want to:

cattery.safely_open_door do
  add_cat(Cat.new)
  add_cat(Cat.new)  
end

Or in one line:

cattery.safely_open_door { add_cat(Cat.new) }

Gorgeous.

So why would you ever want to do this? Well, the easiest way of demonstrating why you might want to create a DSL is to look at one you have already been using, maybe without even realising it. Try to imagine life without this syntax:

Rails.application.routes.draw do
  resources :products do 
    resources :comments
  end
end

Yup. The config.rb routes file in a rails application uses exactly the techniques that have been described here to create a language for you to talk about routing within the routes.rb file. If you output the result of “self” within the routing block you’ll find that it’s one of these:

 #<ActionDispatch::Routing::Mapper:0x000000040a4548>

Anyone who’s been in the game long enough to remember how routes worked in rails 2 may recall that previously routing used to work like this:

ActionController::Routing::Routes.draw do |map|
  map.connect '/products', :controller => 'products', :action => 'index'
  map.connect '/products/:id', :controller => 'products', :action => 'show'
end

And you’ll be hard-pressed to find anyone who wants to go back to that syntax. In conclusion then, instance_exec can help you:

* Write neater code
* Write less code
* Create rich Domain Specific Languages for you and other developers to use

Ruby Gotcha: Setting default Date, Time and DateTime

If you’re using dates, times and datetimes throughout your appliacation, you might find yourself wanting to specify a default format for each. The default formats come back as follows;

[1] pry(main)> Date.today.to_s 
=> "2014-10-28" 
[2] pry(main)> Time.now.to_s 
=> "2014-10-28 13:07:15 +0000" 
[3] pry(main)> DateTime.now.to_s 
=> "2014-10-28T13:07:19+00:00"

In a commercial web application, it won’t be long before you have a manager knocking on your door asking you to change this format to something a little more human-friendly. It is true that you do have a “strftime” method that allows you to do this:

[1] pry(main)> Time.now.strftime("%H:%M") 
=> "13:41"

But if you’re thinking like a programmer, you will not want to be copy/pasting that format all over your application, you’ll want to change it in one place and for that change to be adopted application-wide. In a rails application you may reason that this could be done in an initializer:

# config/initializers/time_formats.rb 
Time::DATE_FORMATS[:default] = "%H:%M" 
Date::DATE_FORMATS[:default] = "%e %b %Y" 
DateTime::DATE_FORMATS[:default] = "%e %b %Y"

Nice and tidy! So let’s check that out in the console…

[1] pry(main)> Time.now.to_s 
=> "13:45" 
[2] pry(main)> Date.today.to_s 
=> "28 Oct 2014" 
[3] pry(main)> DateTime.now.to_s 
=> "13:45"

Oh dear! Although the Time and Date formats have worked correctly, it appears the DateTime format is broken and is only giving us back the time! This is the gotcha – a datetime will cast its value to a Time and return THAT value, with its associated default format. You can see this from the source code: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/DateTime.html#method-i-to_s

dt_lite_to_s(VALUE self) { 
  return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx); 
}

So how do we get around it?

 Solution

There are probably a whole bunch of solutions to this issue, but one is to use one of the more unique features of ruby and monkey-patch the DateTime class:

 
# config/initializers/time_formats.rb 
Date::DATE_FORMATS[:default] = "%e %b %Y" 
Time::DATE_FORMATS[:default] = "%H:%M" 
DEFAULT_DATETIME_FORMAT = "%e %b %Y %H:%M" 
class DateTime 
  def to_s 
    strftime DEFAULT_DATETIME_FORMAT 
  end 
end

Viola

[1] pry(main)> Time.now.to_s 
=> "13:52" 
[2] pry(main)> Date.today.to_s 
=> "28 Oct 2014" 
[3] pry(main)> DateTime.now.to_s 
=> "28 Oct 2014 13:53"

Would be interested to hear about other solutions to this gotcha if anyone else has any ideas.

Moving a WordPress site

If you ever find yourself in the unfortunate position of having to work with wordpress, you may have run into problems when deploying to live. Imagine you’ve got a wordpress site all set up locally and you’re ready to deploy to an expectant client. You might have used a custom theme, entered the content for the client and maybe diddled with the source files a bit, but it’s all working locally so what could possibly go wrong? Surely this is just a case of changing the config file, ftp’ing up the scripts and restoring the database right?

Erm… no.

Lots can go wrong.

  • You might find that once the site is live it still tries to direct you to localhost.
  • You might find you lose all your theme options if you’ve used a paid theme.
  • You might find that some of the content is gone, or hyperlinks within the content are still linking to localhost.

 

A lot of these issues are caused by hard-coded urls going into the database, and these don’t automatically update when you switch to live.  A simple find-replace on the SQL file won’t do it either because some plugins and themes work out their caching by counting the number of characters in a database field, and if you change it without going through the various script hooks you’re going to mess it up. Deploying a WordPress site to live *should* be a doddle, but things can go wrong. Below is the recipe we found works best when doing the first push to live.

Preparation

Make sure the site is working as you want it locally. Once you’re sure it’s working and connected to a database and so on, back up both the site and the DB and keep them safe as the next steps will alter both.

Preparing the database

Save yourself many headaches and get hold of a copy of the wordpress command line tool (http://wp-cli.org/) – installation instructions are on the site.

Once that’s installed, navigate your terminal into the root folder of the site you want to put live and enter the following commands (remembering to add a port to “localhost” if you’re using a different port, and replacing “whatever.com” with your live domain name):

wp search-replace 'localhost' 'whatever.com'

You will then see all the tables that got updated (make sure there’s some numbers in there so you can be sure that it did find/replace the domains!). Next there are two settings in the wp-options table. You can update these on the menu in the wordpress console, but you can’t get to the menu when it’s live because the site uses these settings to direct you to the homepage etc. so you need to change them before going live. If you try and update them in the dashboard of your local version, it’ll break your local version too because THAT will try to get to the live url. It’s a catch-22! wp cli helps again, these two commands will update those settings;

wp option update home 'http://whatever.com'
wp option update siteurl 'http://whatever.com'

Then back it up. That’s the database you’ll restore to live.

Edit the config

Just one last script to go. In the site’s root folder you’ll find a file called “wp-config.php”. There are four database related fields in there that you need to update to the live equivalents, which are “DB_NAME”, “DB_USER”, “DB_PASSWORD” and “DB_HOST”. If you don’t already know these, your hosting provider should be able to tell you (or, it’ll tell you while you’re setting it all up).

Good to go!

With all that done, just ftp the files up to where you want them and import your local database to live. Update DNS and you should be cooking!

I hate wordpress. The irony that this is a WordPress blog is not lost on me :)

Using Datamapper with Rails 4

Was trying to swap out active record for datamapper on a rails 4 application this morning and had one or two issues with gem version conflicts (I think this is largely due to DM being discontinued in favour of the not-done-yet ROM). At time of writing if you install with rails 4.0.0 and just go for the rubygems repo you’re going to get moaned at for having incompatible gems.

For a fresh rails 4 application you can get around this by installing from github and specifying “release-1.2” as the branch. I managed to get the full suite up and running by adding the following to my Gemfile (adapted from this guide).

%w{core constraints migrations transactions timestamps do-adapter rails active_model sqlite-adapter}.each do |gem|
  gem "dm-#{gem}", :git => "https://github.com/datamapper/dm-#{gem}.git", :branch => 'release-1.2'
end

What does it do? Basically, it iterates through a bunch of strings interpolating those strings into a gem name and git repo name, and for each one, specifies branch “release 1.2” and gets the gem for that. Whoever maintains those repos has certainly been consistent!

Interactive fiction – a primer

Okay so I’ve just finished my first interactive fiction, The Scarecrow. I wouldn’t say this was enough for me to call myself an “interactive fiction author” and I certainly wouldn’t call myself a writer (seriously, I’m just this computer nerd from Birmingham!) but I do see it as being a bit of a milestone for me as I’ve been a fan of this genre of writing for some years now. There is a chance that through these posts, some of my friends and followers may have become interested in the genre and so I’m making this post just to give any potential fans a gentle nudge in the right direction.

There’s loads of guide online about how to get an interpreter set up, so I won’t go through that here I’ll just link to this.

In terms of authors – the landscape is pretty rich… it would be dismissive of me to just point you straight in the direction of “the ones you gotta read”, so all I’ll say is that my favorites are Emily Short and Andrew Plotkin. We’ll leave it at that.

The other thing to understand is that these days, the factor that seperates the dogs from the puppies is *quality*. Given that these works are mostly free, that means you have a whole wealth of quality literature right there and readily available, provided by a community who would be delighted if you read and enjoyed their works.

In terms of where to find good IF, this is the joint right here. Either that or a good google search.

Annually, the IF community hold a competition in the month of September (one I hope to take part in next year). The quality is always very high in the competition, this years entries should be appearing here soon. Previous years entries are also available for download from the IF database.

Anyway, hopefully this should be enough to get people started if they’re interested. Peace out \m/