Friday, 21 December 2012

Poor man's guide to managing Ruby versions

Understanding the guts of Ruby Version Management by rolling your own

I've been tinkering with a fresh install of Ubuntu 12.10, setting up a nice clean development environment. One of the first things to do, of course, is implement some sort of Ruby version management. RVM and rbenv seem to be the clear winners in this arena, though there are a lot of tools out there that do a similar job.

Writing your own version management for your Rubies isn't actually all that difficult. At it's core, we need need two things:

  • A way to segregate the executables of the various versions
  • A way to call the versions at will

Segregating versions is trivial - working with files and folders, we can put the various versions into named directories.

Actually executing our different versions is not all that difficult either. One way would be to create aliases with version numbers and explicitly call those when we want to use them. The more popular way, however, is to manipulate our PATH variable. The PATH variable tells our operating system where to look for executables when we, for example, type a command into the terminal. The first match it hits is the one it uses.

Using this idea, it isn't all that difficult to set up our own poor man's Ruby version management.

But Why?

Why would anyone want to do this when there are already tested and stable versions out there?

Simple - because we can! Really, though, this is an experiment, a little tinkering that will further your own understanding and even if you don't actually use this for your own version management, it will give you a better appreciation of what's going on behind the scenes of your favourite Ruby environment management system.

Step 1 - Get and compile your rubies

To pull off this experiment, we are going to need two distinct versions of Ruby. I'm going to use a 1.9 and a 1.8. The advantage is it is easy to test which we have running with some simple Ruby string commands because of the changes between the versions.

Download Ruby 1.9.3-p327 and Ruby 1.8.7-p371. Now extract the archives:

$ tar -zxvf ruby-1.9.3-p327.tar.gz
$ tar -zxvf ruby-1.8.7-p371.tar.gz

Step 2 - Set up some directories

I'm going to create a directory called ".pmrbm" in which to stash my Ruby versions. Inside that directory, I'll create an explicit 1.8.7-p371 and 1.9.3-p327 directory:

$ mkdir -p $HOME/.pmrbm/1.8.7-p371
$ mkdir $HOME/.pmrbm/1.9.3-p327

Step 3 - Compile

Compiling Ruby from source might sound scary if you've never done it before, but really it's a walk in the park. We should have two directories in our downloads folder (from the unarchiving we did earlier) - one for the 1.8.7 and one for the 1.9.3 versions. As we compile our versions, we will pass in the path into which we want the compiled Ruby to end up with the "--prefix" command:

$ cd ruby-1.8.7-p371
$ ./configure --prefix=$HOME/.pmrbm/1.8.7-p371
$ make
$ make install

And you should have Ruby 1.8.7-p371 installed. Now we do the same for our 1.9.3-p327 version, but obviously substituting our 1.9.3 specific paths in:

$ cd ruby-1.9.3-p327
$ ./configure --prefix=$HOME/.pmrbm/1.9.3-p327
$ make
$ make install

We've now got two versions of Ruby compiled on our machine.

Win

How on earth are we going to use our Ruby versions? Well, if you are paranoid, you could cd into the various directories and confirm that Ruby is installed and running in those directories. I'll skip that step and simple start modifying my PATH. My system had a fresh install of Ubuntu on it, with no system Ruby installed, so at this point, even though I've compiled two different versions of Ruby, if I try to interrogate the version of Ruby on my system, I will get an error:

$ ruby -v
$ The program 'ruby' can be found in the following packages:
...

Obviously, I'm not going to install Ruby from apt-get, because that would defeat the object of this exercise. Instead, I'll type the following:

$ export PATH="$HOME/.pmrbm/1.8.7-p371/bin:$PATH"

And now when I can get the Ruby version (note I'm in my home directory, but you can be in any directory you want, the PATH will make sure that the OS can find your 1.8.7 version of Ruby:

$ ruby -v
$ ruby 1.8.7

If I run some code in irb, I can confirm that I'm running 1.8.7, because of the way it handles single string characters:

$ irb
> "cat[1]"
=> 97

Great, but what about 1.9.3? Easy as pie - simply change your PATH:

$ export PATH="$HOME/.pmrbm/1.9.3-p327/bin:$PATH"

Again, check the version and confirm with a little bit of single string manipulation:

$ ruby -v
$ ruby 1.9.3p327
$ irb
> "cat[1]"
=> "a"

Note that I was pretty sloppy there with the PATH. For example, if you were to examine your PATH variable at this point, you should see something like(your path will obviously vary based on your system setup):

$ echo $PATH
/home/rubyflewtoo/.pmrbm/1.9.3-p327/bin:/home/rubyflewtoo/.pmrbm/1.8.7-p371/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin/usr/bin:/sbin

See, both the ruby versions are present in the path, though at the moment, ruby is reporting it is version 1.9.3 because the first path that the OS finds Ruby in is 1.9.3-p327/bin, so it simply ignores the 1.8.7 path later in our environment variable. You can, if you feel like playing with this, move the 1.9.3 directory, and test again to see that the OS would then pick up the 1.8.7 version. So

$ mv ~/.pmrbm/1.9.3-p327 ~/.pmrbm/1.9.3-p327.back
$ export PATH=$PATH
$ ruby -v
ruby 1.8.7

Obviously, a neater solution would be to remove the portions of the PATH that are not needed rather than continually pre-pending to it

What now?

Now you should trash all of the above and go use one of the existing stable and actively maintained solutions. A few options:

Tuesday, 11 December 2012

Rails 3.2, MiniTest Spec and Capybara

What do you do when you love your spec testing with Capybara but you want to veer off the beaten path of Rspec and forge ahead into MiniTest waters? Follow along, and you'll have not one, but two working solutions.

The setup

Quickly now, let's throw together an app to test this out. I'm on rails 3.2.9.

$ rails new minicap

Edit the Gemfile to include a test and development block

group :development, :test do
  gem 'capybara'
  gem 'database_cleaner'
end

Note the inclusion of database_cleaner as per the capybara documentation

And bundle:

$ bundle

We will, of course, need something to test against, so for the sake of it, lets throw together a scaffold, migrate our database and prepare our test database all in one big lump. If you are unclear on any of this, go read the guides.

$ rails g scaffold Book name:string author:string
$ rake db:migrate
$ rake db:test:prepare

Make it minitest

To make rails use minitest, we simply add a require statement to our test_helper.rb:

require 'minitest/autorun'
require 'capybara/rails'

We can add in a quick integration test to verify that everything is working correctly up to this point:

$ touch test/integration/book_spec.rb

If you are that way inclined, you could create an "acceptance" directory and pop your tests in there instead. I'm not too bothered by the naming right now, because this is a proof of concept.

Now edit the book_spec.rb file we created

require 'test_helper'

describe Book do
  it "creates a new book" do
    1.must_equal 1
  end
end

Running this passes nicely:

$ ruby -Itest test/integration/book_spec.rb

Setup is complete. We have a nice little project with which to experiment.

Failing to use Capybara

At this point we can try to throw in some navigation from the Capybara DSL to see if it will work. Update book_spec to include "visit":

describe Book do
  it "creates a new book" do
    visit('/books/new')
    1.must_equal 1
  end
end

and you will get an error when you run the test again - something to the effect of

$ NoMethodError: undefined method 'visit' for #<#:0x43c20f0>

Fix what you break

The rest of this post will focus on getting this small piece of code to work. I've found two ways so far. I'll present both and you can decide which you prefer.

The way of the Severed Rodent Hand

Pinched pretty much verbatim from the excellent rstat.us project, the Way of the Severed Rodent Hand uses a module. Working from the principle of the simplest thing that works, I'm going to start out in book_spec.rb and do this:

describe Book do
  Include Capybara::DSL
  it "creates a new book" do
    visit('/books/new')
    1.must_equal 1
  end
end

This produces a passing test. Dig a little deeper though and we will notice that the Capybara documentation suggests using a teardown method to instruct DatabaseCleaner to clean our database as well as reset sessions. MiniTest supports teardown hooks, but we will use and after method to start with:

describe Book do
  Include Capybara::DSL
  after do
    DatabaseCleaner.clean       # Truncate the database
    Capybara.reset_sessions!    # Forget the (simulated) browser state
    Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
  end

  it "creates a new book" do
    visit('/books/new')
    1.must_equal 1
  end
end

Our tests work - and everything is right with the world.

Sever

Of course, no self respecting rubyist is going to leave this code as it stands. As soon as we add another resource, we will be duplicating the after block. Instead, we are going to sever that code and create a module, just like rstat.us. I'm going to put this into my test_helper file for simplicity but on a larger project, you might prefer to use a dedicated integration_helper or acceptance_helper:

module IntegrationTestHelper
  include Capybara::DSL
  
  def teardown
    DatabaseCleaner.clean       # Truncate the database
    Capybara.reset_sessions!    # Forget the (simulated) browser state
    Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
  end
end

I've also taken the opportunity to move the code from "after" into a teardown hook - MiniTest will pick this up for us because it is just awesome! To complete this refactor, we must include our module into our spec. Open up book_spec again and change it a little:

describe Book do
  include IntegrationTestHelper

  it "creates a new book" do
    puts 'create'
    visit('/books/new')
    1.must_equal 1
  end
end

Our tests still pass. We are golden.

The Classical method

Using a module as we just did works well. Nothing to fix there. However there's a trade-off, we have that little "include IntegrationTestHelper" in all our test that need access to Capybara's DSL. We can swap out this inconvenience for a slightly different one - this one based on classes instead of modules. It has it's own inconvenience, but you pay's your money, you takes your choice.

Set up a class

This method relies on a class in our test_helper - let's code it up like this:

class IntegrationHelper < MiniTest::Spec
  include Capybara::DSL
 
  after do
    DatabaseCleaner.clean
    Capybara.reset_sessions!
    Capybara.use_default_driver
  end
end
MiniTest::Spec.register_spec_type( /Integration$/, IntegrationHelper )

The magic here is the last line - this basically says that for any test that is described as "Integration", set the parent to IntegrationHelper (and thus inherit all the goodness of the DSL and the after block). Of course this magic can only be hooked up if we change book_spec to include the word Integration in our initial describe:

describe 'Book Integration' do
  #include IntegrationTestHelper

  it "creates a new book" do
    visit('/books/new')
    1.must_equal 1
  end
end

This passes. Changing your register_spec_type regex to something like "/Integration$/i" and you will have a case insensitive match if you prefer to use normal english casing on subsequent words.

Wrap up

Two methods, both work. On the one hand, you have to "include", on the other hand you have to describe correctly but you get a class hierarchy. I know religious wars have been started over less, but I encourage you to try both and go with your gut. If you have a better/another way, drop me a comment and share the love.

Friday, 23 November 2012

Ruby, facemash and the Elo rating system via BDD

Reproducing the Elo rating algorithm in Ruby is a little challenge that I took upon myself recently for a small hack. The same Elo rating system that was scrawled upon the glass in "The Social Network" as the algorithm that Mark Zuckerberg used on rank people on FaceMash. As an exercise, here's a pass at it with a little BDD thrown in for good measure.

A new file - elo.rb:

require 'minitest/spec'
require 'minitest/autorun'


describe "result" do
  describe "when both players start with rating of 100 and k factor of 30"  do
    it "must return 115 for the winner" do
      new_rating.must_equal 115
    end
  end
end

Starting a new algorithm is always tricky. We know that the Elo rating system is essentially concerned with assigning ratings to players based on the outcome of their games or matches. In fact, it is widely used as a chess ranking algorithm. At a first glance then, I thought I might want to jump in and start modelling some objects - players, games, ratings, player ranking. But that sounds like a big bite. A lot can go wrong with hunches.....bunches of hunches and hunches in bunches.

Small steps then - what are we doing? The big picture. The major output we want is a new rating! Our first test tries to check that the new rating is equal to 115. Why 115? Because the excellent online elo calculator told me so when I typed a bunch of numbers in there.

The numbers

To get some numbers, I first read wikipedia's entry on the Elo rating system. The algorithm relies on each player having a rating, each game delivering a score to each player and the mysterious "k" value.

I decided, rather arbitrarily, to assume that in my two player match, each player starts with a rating of 100. We could, equally have started with 0, but 100 felt right. Similarly, each player starts with a k value of 30. Using any method you fancy (the aforementioned online elo calculator, or even, working it out by hand), a winner in the above scenario, would have a new rating of 115.

Of course, running our code fails miserably:

Loaded suite elo
Started
E
Finished in 0.001000 seconds.

  1) Error:
test_0001_must_return_115_for_the_winner(ResultSpec::WhenBothPlayersStartWithRatingOf100AndKFactorOf30Spec):
NameError: undefined local variable or method `new_rating' for #<ResultSpec::WhenBothPlayersStartWithRatingOf100AndKFactorOf30Spec:0x28a8830>
    elo.rb:8:in `block (3 levels) in <class:TestElo>'

1 tests, 0 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 62642

Player

We can get this to pass by declaring new_rating = 115. That would be very baby steps. I'm going to go a little faster. We are dealing with a "new rating". What has a rating? A player has a rating. Let's go with that for a moment and create a Player class.

class Player
  attr_accessor :rating
end

describe "result" do
  describe "when both players start with rating of 100 and k factor of 30"  do
    it "must return 115 for the winner" do
      winner = Player.new
      new_rating = winner.rating
      new_rating.must_equal 115
    end
  end
end

Run this and we still fail. However, we fail because our new rating is not 115 as we expect in our test.

  1) Failure:
test_0001_must_return_115_for_the_winner(result::when both players start with rating of 100 and k factor of 30) [elo.rb:19]:
Expected: 115
  Actual: nil

Getting rid of our nil is easy - we can define a new Player to default their rating to 100 if it isn't specified.

class Player
  attr_accessor :rating

  def initialize(rating=100)
    @rating = rating
  end
end

And our test starts to produce some more meaningful failure

  1) Failure:
test_0001_must_return_115_for_the_winner(result::when both players start with rating of 100 and k factor of 30) [elo.rb:19]:
Expected: 115
  Actual: 100

Current rating, New rating

Implied in all this Elo business is the idea that at some point, we will calculate the new rating based on a game between our players. To that end, we want the ability to update a player's rating based on a game outcome. That sounds like a pretty tall order. It starts me thinking towards game objects and....tooooooo complicated. Let's rather put some functionality into Player in the meantime - just to get it working.

class Player
  attr_accessor :rating

  def initialize(rating=100)
    @rating = rating
  end

  def calculate_new_rating
    @rating = 115
  end
end

describe "result" do
  describe "when both players start with rating of 100 and k factor of 30" do
    it "must return 115 for the winner" do
      winner = Player.new
      winner.calculate_new_rating
      new_rating = winner.rating
      new_rating.must_equal 115
    end
  end
end

Putting the above code together, our tests pass! Great - now all we have to do is write the code to actually do the calculation.

Calculating Elo

Looking back through Wikipedia and translating the algorithm into Ruby, we might end up with something like the following:

  def calculate_new_rating
    new_rating = rating + k_value * (score - expected_outcome)
  end

The k value, as we mentioned earlier, is going to be 30. Score is either 1 or 0 (win or lose - we ignore draws for now). That just leaves us with expected outcome.

Expected rating

We need to have expected outcome in place before we can calculate our actual new rating based on the outcome of our game. Time to code up the equation for expected outcome. I'm going to put it into Player for the moment. It might not actually belong there in the end, because an expected outcome sounds like something that should belong to a Game. But it is a start. Simply copying the formula from Wikipedia, we get the following piece of code:

  def expected_outcome
    1.0/(1 + 10**((opponent_rating - @rating)/400))
  end

Things to note

  • We are raising to a power - in Ruby we use ** to achieve this.
  • We need the opponent's rating
  • We should probably think about floating point arithmetic

We've meandered away from our tests at this point. Let's get back to them and start testing our expected outcome, we should have written this first really:

  describe "expected outcome" do
    it "must return 0.5 when ratings are equal"
      winner = Player.new
      winner.expected_outcome.must_equal 0.5
    end
  end

Even if you don't know the Elo algorithm inside and out - this makes sense - given two opponents who are the same level, the chances that one will win should be 0.5. The algorithm is fairly well documented though, and if you are inclined, you can hunt around and find tables of expected outcomes based on differences between opponent ratings. Running the above crashes - an undefined variable 'opponent_rating'. I'll make it a parameter

  def expected_outcome(opponent_rating)
  ....

Which gives us a wrong number of arguments error. We need to update our test and pass in an opponent rating

  describe "expected outcome" do
    it "must return 0.5 when ratings are equal"
      winner = Player.new
      winner.expected_outcome(100).must_equal 0.5
    end
  end

Passing tests. Good. Now we can flesh out that new rating algorithm. Feeling confident, I'm changing a fair amount in one go here, let's hope it works:

  def calculate_new_rating(score, opponent_rating)
    @rating = rating + 30* (score - expected_outcome(opponent_rating))
  end

and fixing our test

it "must return 115 for the winner" do
  winner = Player.new
  winner.calculate_new_rating(1, 100)
  new_rating = winner.rating
  new_rating.must_equal 115
end

Wow - it's good! Let's discuss the code a bit - I changed the calculate_new_rating method to take two parameters - a score and the opponent rating. Then I substituted 30 in for the k_value - at some point this should become a constant perhaps, or a parameter. I also set our rating instance variable upon calculating the new rating. This means that any time I call calculate_new_rating on a Player, it will update that player's rating to be their new rating. I guess I could start running around and adding in variables for current rating, old rating and such, but this feels a bit cleaner to me - you have a rating - as soon as a game is played, your rating should change to reflect that. I am passing in score - currently 1. In our implementation, it will only ever be 1 or 0 - games can be won or lost, and never tied (we are, after all, implementing a facemash like algorithm - there are no draws).

Improvements

This code is a first draft - a good working example - it has its drawbacks though, which become apparent when you start adding in more tests, and especially when you test the very real scenario of calculating the ratings of two players, one after the other. I'll leave you to play with it a bit and see if you can spot the gotchas. I'll pick it up again next time.

Monday, 12 November 2012

Stop asking for a ninja when you actually want a samurai

From the various appropriate entries on Wikipedia about ninja and samurai (emphasis mine)

A ninja or shinobi was a covert agent or mercenary. The functions of the ninja included espionage, sabotage, infiltration, and assassination
The shinobi proper, a specially trained group of spies and mercenaries
Samurai were the military nobility
Samurai felt that the path of the warrior was one of honor, emphasizing duty to one's master, and loyalty unto death

Now which one do you really want working for you?

Thursday, 8 November 2012

Overriding equality and Test Driven Development

Ruby has, at its root, an Object. Methods available in Object are available to every class because every class in Ruby inherits from Object somewhere in its own class hierarchy. Of course, you can override methods in subclasses, changing the functionality of a root method.

You might stumble on to this idea if you work through Test Driven Development By Example by Kent Beck, translating the Java code into Ruby as you go. At some point pretty early on, he overrides the equality method on the Currency class to better test if two instances are equal. I'm going to do the same here, working with Instruments instead of Currency.

Equality

Equality in Ruby can be expressed using any of the following three methods

object == other
equal?(other)
eql?(other)

These methods are defined on the base Object. The default implementation of equality will only return true if both objects are exactly the same. The interesting thing is that although these three methods start out functioning the same, the documentation does note the difference between them:

Equality—At the Object level, == returns true only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning. Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b). The eql? method returns true if obj and anObject have the same value. Used by Hash to test members for equality.

So we are encouraged to override == to test equality of our own classes and objects.

Instruments in irb

Let's put together a simple implementation to see how this works. Fire this up in irb:

class Instrument

  def play
    puts 'lovely sound'
  end

end

guitar = Instrument.new
=> #<Instrument:0x2a1b9d8>
another_guitar = Instrument.new
=> #<Instrument:0x2940c70>
guitar == another_guitar
=> false
guitar.equal?(another_guitar)
=> false
guitar.eql?(another_guitar)
=> false

You get the idea. The two guitars are not equal. Everything functions as per the documentation. Just for completeness, Ruby considers an object to be the same when it is *exactly* the same - keep typing:

third_guitar = guitar
=> #<Instrument:0x2a1b9d8>
third_guitar == guitar
=> true

That makes sense and behaves as per the documentation. Equality tests that the "actual" objects are equal. This is the equivalent of saying, in the real world, no two guitars are the same - even if they are both, for example, Ibanez Jems (see what I did there? ruby gems, guitar jems) with the Floral pattern that came off he production line one after the other.

Okay, the pedantic among you will argue that they won't be the same, the floral pattern will probably be a bit different - that was the point of Jems right? The tone might be a little different, the feel will be different - minutely different, but different none the less. Buuuuuut, I would argue, to all intents and purposes, these two fictional guitars are the same. They will have the same price tag, they will play pretty much identically (in double blind playing trials), they have the same number of pickups, same number of frets, same volume and tone potentiometer, same pickup-selector switch. They both have the same monkey handle, they will both produce the same note when tuned to A440.

The same

Given the above, for our example, we are going to say they *are* the same. In fact, to make it even simpler to show the code, I'm going specify that any 'guitar' is the same as any other 'guitar' (like Bruce Lee said "A kick is a kick, a punch is a punch").

To represent this in Ruby, we have to override object equality and put in its place, our own code to compare two instruments. That sounds a little scary to just bash out and I heard the word "specify" a few sentences ago, so I'm going to wire up some tests using the awesome minitest (last seen integrating into Rails) to help us code this and see where we get to.

Using various asserts included in our testing framework, we can test equality of objects because things like assert_equal actually just take the two objects and call the "==" method on those objects. Climb out of irb and create yourself a new file - I'm calling mine minstrel.rb:

require 'minitest/autorun'

class TestInstruments < MiniTest::Unit::TestCase

  def test_guitars_are_guitars
    guitar = Instrument.new
    another_guitar = Instrument.new
    assert_equal guitar, another_guitar, "guitars should be guitars"
  end

end

Pretty easy right? We require our minitest library and create a new class that inherits from MiniTest::Unit::TestCase - because that's how you use minitest :). Then we set up our first little test, create two guitars and try to test the assertion that they are equal. Running this, of course, fails miserably:

Started
E
Finished in 0.000000 seconds.

  1) Error:
test_guitars_are_guitars(TestInstruments):
NameError: uninitialized constant TestInstruments::Instrument
    minstrel.rb:10:in `test_guitars_are_guitars'

1 tests, 0 assertions, 0 failures, 1 errors, 0 skips

And we can meander down a small intro to Test Driven Development if we fancy, but that's not really what I'm trying to show here. Instead, I'll just add our Instrument class that we played with in irb up above. A bit messy because I'm putting all my code in minstrel.rb....

require 'minitest/autorun'

class Instrument

  def play
    puts 'lovely note'
  end

end

class TestInstruments < MiniTest::Unit::TestCase

  def test_guitars_are_guitars
    guitar = Instrument.new
    another_guitar = Instrument.new
    assert_equal guitar, another_guitar, "guitars should be guitars"
  end

end

Now I can run the whole shebang again:

  1) Failure:
test_guitars_are_guitars(TestInstruments) [minstrel.rb:12]:
No visible difference.
You should look at your implementation of Instrument#==.
#

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

That' very interesting - look - it fails the assertion, but it actually tells us that there is no visible difference. Further, it points us nicely towards the method we should be examining which is, coincidentally, our equality on Instrument. Of course it is the equality method that is inherited from our base Object class, because as yet, we haven't defined an equality method explicitly.

Defining equality

At last we come to our point - how to override equality on our objects. Baby steps - I'm going to make my assertion pass by overriding equality in my Instrument class and always return true - not our final implementation, but, it is a start:

class Instrument
  
  def ==(other)
    true
  end

  def play
    puts 'lovely note'
  end

end

Running my tests now gives this output

# Running tests:

.

Finished tests in 0.000542s, 1845.7745 tests/s, 1845.7745 assertions/s.

1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

Great success

We have successfully overridden our equality method. Of course our implementation is not complete - because any instrument will be considered equal to any other instrument at this point. One implementation is to expose an Instrument Type property on Instrument. Initialize any instance with a type and then test the types are the same for our equality. You might end up with something like this:

minstrel.rb:

require 'minitest/autorun'

class Instrument
  attr_reader :type

  def initialize(type)
    @type = type
  end

  def ==(other)
    @type == other.type
  end

  def play
    puts 'lovely note'
  end
end

class TestInstruments < MiniTest::Unit::TestCase

  def test_guitars_are_guitars
    guitar = Instrument.new('guitar')
    another_guitar = Instrument.new('guitar')
    assert_equal guitar, another_guitar, "guitars should be equal"
  end

  def test_guitars_are_not_violings
    guitar = Instrument.new('guitar')
    violin = Instrument.new('violin')
    refute_equal guitar, violin, "guitars should not be violins"
  end

end

All over overriding

That's it - we started out on a simple mission to override our method to test equality between classes, came up with a contrived example that differs from the standard Currency example in Kent Beck's book, and ended up with a little test suite toboot. The take home message - override equality by defining your own method called "==" with one param of (other).

Tuesday, 16 October 2012

Rails Callbacks and Boolean Values

Rails has a lovely feature as part of ActiveRecord - Callbacks; to wit:

Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic before or after an alteration of the object state

Basically, that means that you can instruct Rails to execute your own code throughout the process of creating, updating and destroying objects/records. You can, for example, use them to set some default values on create, or perhaps do some last minute validation, or even fire an event just after you've saved a record. The available callbacks are:

  • after_initialize
  • after_find
  • after_touch
  • before_validation
  • after_validation
  • before_save
  • around_save
  • after_save
  • before_create
  • around_create
  • after_create
  • before_update
  • around_update
  • after_update
  • :before_destroy
  • around_destroy
  • after_destroy
  • after_commit
  • after_rollback

At the same time, Ruby methods have the concept of implicit return values. That is to say, any method will return the value of the last evaluated statement. This is neat - you don't need to write an explicit "return" at the end of your methods.

When we mangle these two features together, we can create subtle bugs in our code. Well not so subtle, because your code will just stop working the way you expect, and it can be fairly difficult to debug because no error is thrown.

Consider the Rails Callbacks again:

If a callback returns false, all the later callbacks and the associated action are cancelled

And I'm sure you'll see where I'm going with this now.....Take an example where you have a boolean value as one of your fields in your model. You want to set this boolean in a callback, either as a default value or because it represents some state based on some other logic.

Let's contrive an example - a blog application which allows comments. We want comments to be moderated of course, because spam is bad. We create a quick boolean on our comment model called "isinmoderation". Every time a new comment is submitted, we want to set this variable to true. We have an added piece of logic to trust any comments from readers who have submitted five good (non-spammy) comments.

Given the above, we might end up with something like the following:

class Comment < ActiveRecord::Base
  before_create :moderate

  protected
    def moderate
      unless is_from_trusted_reader
        this.isinmoderation = false
      end
    end
end

We run some tests and find that new comments from untrusted readers are not being saved to the database. We notice that our transaction is being rolled back, but there's no error. For a while, we are confused. And then we remember this blog post and realise that we are returning a falsey value from one of our callbacks....and, as the Rails docs say,

all the later callbacks and the associated action are cancelled

And the mystery is solved. So is there an elegant way to ensure we don't hit this condition? Well one way out is to explicitly declare a return of true from our moderate method. It is a little less elegant than the normal implicit return, but c'est la vie

Monday, 8 October 2012

Install or update gems behind corporate firewall or proxy server

If you work with Ruby on Windows in a corporate environment, sooner or later, you will hit an error when you are trying to install or update Gems. In my case, I simply had to set a few environment variables and I was good to go. RubyGems uses the HTTP_PROXY, HTTP_PROXY_USER and HTTP_PASS by default so if you open up a command prompt and set these as follows, it will use them to find the proxy and authenticate you to your proxy server:

set HTTP_PROXY=http://pr.oxy.ip:port
set HTTP_PROXY_USER=domain\user.name
set HTTP_PASS=sUp3rS3curepAs$w0rd

Extra points: A reader sent me a comment that this will only work when the proxy is using basic authentication. If you're having trouble using this method then you can give ntlmaps a shot. It's basically a little bit of python magic that sets up a proxy on your localhost through which you can route traffic and it will handle the authentication with your proxy server for you.

Thursday, 4 October 2012

Ruby on Rails - mapping a url to a resource

There are always times when you need to override the default RESTful routes in Rails. The most common case for this is mapping a /logout url to a session#destroy controller and action. However, this simple example doesn't really help when you want to achieve something a little more intricate - for example using a completely different url for a resource. Examples include a blog when you want your urls to add blog posts to be /add rather than blogs/new. Or what about a application with a Users model that has different types of users that can be added - perhaps it is a medical database and you have Doctors and Nurses - you want your urls to reflect the kind of person you are adding or editing - so doctor/new or nurse/new rather than users/new.

Mapping urls like this is easy. However there is a little gotcha that you have to be aware of. Let's walk through an example and we'll see how to make it work

New project

We'll create a simple project for this example - a hypothetical book review site. We are going to have a model called BookReview obviously, and we will create it with a couple of properties - book_name and book_review. In a Rails project, run a quick scaffold and migrate to get things up and running fast.

$ rails g scaffold BookReview book_name:string book_review:string
-----
$ rake db:migrate

Decide on our URL structure

Since this is a trivial example and our site will have no input other than book reviews, we want to use /add as our url to add a book review. This is only slightly neater than the default routes of book_reviews/add, but it serves us well for the sample.

Edit your routes

To map a url to a resources, we have to edit config/routes.rb. Currently it looks like this:

BookReviews::Application.routes.draw do
  resources :book_reviews
end

We will start by making Rails aware of our /add url. Edit your routes.rb to look like this:

BookReviews::Application.routes.draw do
  resources :book_reviews
  match 'add' => 'book_reviews#new'
end

Now if you fire up your application with rails s, you can navigate to localhost:3000/add and you should get something similar to this:

This is great - and you might be tempted to stop here, because it all looks good, however, let's add a small constraint to our application - we want to make a field mandatory - book_name for example. Edit app/models/book_review.rb and add in a constraint to ensure book_name is filled in.

class BookReview < ActiveRecord::Base
  attr_accessible :book_name, :book_review
  validates_presence_of :book_name
end

Oh no, our url changes on error

When we visit /add to add a book review and we forget to enter a book_name, our model will not save. Rails neatly handles that for us and provides a flash to tell us that we need to supply a book name. Unfortunately, our url is no longer /add! Try it out - leave off the book name and you'll be redirected to /book_reviews with the flash message!

This is annoying the url that renders is not /add but /book_reviews. Why? Well, the book_review controller responds to actions at /book_reviews - the action to create a book review is a "post" - you can see this if you view source on the /add url or book_reviews/new url (they are both the same thing at the moment). We have a form that is declared like this:

<form accept-charset="UTF-8" action="/book_reviews" class="new_book_review" id="new_book_review" method="post">

When we submit the form, it posts back to /book_reviews. Rails does a little magic and sends the request to our book_review controller's create end point. The create action tries to save the model, fails and decides to render the "new" view - no redirect, no changing of the url....so we are stuck at book_reviews.

Is that so bad?

Well, in and of itself, this isn't so bad really. And to be honest, most users probably wouldn't even notice. However, we are perfectionists and we want our urls to be consistent, if we started on /add and we get an error, we want to return to /add and report the error. And believe me, this is really useful if you've inherited an application and the last programmer jokingly named some resources with less than appropriate names!

Change the url

"Aha" I hear you say "If the form's postback url is causing us problems, let's just change that". Good thinking batman, let's try it out. Edit views/book_reviews/_form.html.erb, changing the form_for helper

<%= form_for(@book_review, :url=> "/add") do |f| %> 

Go back to your browser and try it out - submit a review without a book name. Hmmm that's not quite right is it? When we submit now, we end up at the "/add" url, but we don't get the flash message telling us that we need a book_name anymore. If we fill in book_name, it doesn't actually save it either. Well that makes sense because our route that we defined earlier instructed Rails to render our book_review#new action whenever we visit "/add"- so that's what happens - we never ever hit our create action in the controller!

More routes

Here's the real magic - we can specify our route matching to respond to different http verbs with the handy :via property. Change your config/routes.rb to look like this:

BookReviews::Application.routes.draw do
  resources :book_reviews
  match 'add' => 'book_reviews#new', :via => :get
  match 'add' => 'book_reviews#create', :via => :post
end

We have kept our original route that matched "/add" to our "new" action in our book_review controller, but we have instructed Rails that this should only handle the "get" http verb. We have added in a new route matching "/add" with a "post" http verb and told Rails that when this happens, we should let the book_review controller's create action handle things for us.

Eureka!

Now when we visit "/add" and leave out a book_name, we get sent right back without the saving, as we should, we also get our flash message *and* we remain on the "/add" url!

Your turn

This is a workable solution at the moment. There are a few things to clean up though - note the _form partial will serve up both new and edit actions for book reviews. That means on edit, you'll currently be redirected to "create" (remember, we have manually specified a url). You should tidy that up with a little logic, unless you aren't offering edit functionality. The other little loose end is the nasty somewhat magic string in your _form partial specifying the "/add" url. We can tidy that up in Rails by creating a named route, but I'll cover that in another shorter post.

Friday, 21 September 2012

Getting started with Ruby on Rails 3.2 and MiniTest - a Tutorial

For fun, I thought I would start a new Ruby on Rails project and use MiniTest instead of Test::Unit. Why? Well MiniTest is Ruby 1.9s testing framework dejour, and I suspect we will see more and more new projects adopt it. It has a built in mocking framework and RSpec like contextual syntax. You can probably get away with fewer gems in your Gemfile because of that.

Getting started is always the hardest part - let's jump in with a new rails project

rails new tddforme --skip-test-unit

Standard stuff. MiniTest sits nicely next to Test::Unit, so you can leave it in if you prefer. I've left it out just to keep things neat and tidy for now.

Now we update the old Gemfile:

group :development, :test do
  gem "minitest"
end

and of course, bundle it all up.....from the command line:

$ bundle

Note that if you start experiencing strange errors when we get in to the generators later on, make sure you read about rails not finding a JavaScript runtime. Fire up your rails server and check everything is hunky dory if you fancy.

A Model

For the purposes of testing our test framework, we are going to put together a small model. Let's call it DevelopmentMethodology and give it a couple of fields - perhaps a name and a description.

$ rails g model DevelopmentMethodology name:string description:string

Set up the test structure

Now we have a model and a migration. I like to write my first tests now. Yes I know, crazy, before I've even migrated......anyway, because I created my project with no test-unit, I don't even have a test directory, so I'll create it now along with a few other subdirectories that will mimic the usual testing structure

$ mkdir test
$ mkdir test/fixtures
$ mkdir test/unit

Now, inside the test directory, I'll set up a basic test_helper file:

$ touch test/test_helper.rb

The code for my test_helper is almost boilerplate - I'm putting the Rails Environment into "test" and loading up the Rails and then simply including the minitest framework.

ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require "minitest/autorun"

If you kept test-unit in your project, you'll have a test_helper already that will look similar to this, but won't yet bring in minitest. In this case you can choose to replace the "require" statement in that test_helper.rb file or you can create a new minitest_helper.rb file with the code.

Petit pause

Let's take a breath - go get a cup of coffee. We've covered a lot of ground. So far, the basic steps we have gone through are:

  • Create a new Rails project, skipping the test-unit framework
  • Update our Gemfile to include the minitest
  • Bundle
  • Create test directory structure
  • Create test_helper.rb

Writing a test

At last, we can write our first test! Create a new file in the test/unit directory - call it whatever you want, I've chosen to name mine "development_methodology_test.rb" and a basic outline goes like this:

require 'test_helper'

class TestDevelopmentMethodology < MiniTest::Unit::TestCase
  def test_our_test_framework_can_fail
    assert false
  end
end

First, we include our test_helper.rb. Then we define a class to test our DevelopmentMethodology model - it inherits from on of the classes in MiniTest. Easy peasy. Then, we create a method called test_our_test_framework_can_fail in which we simply assert false. Why would I bother to do this? Well, this little piece of code allows me to verify that I've set up MiniTest correctly - I haven't yet bothered to write any tests against my own application yet. However, when I run the test, I get valuable output (assuming everything has been set up correctly) and I can see that MiniTest is running and is producing a failing test:

[]$ ruby -Itest test/unit=development_methodology_test.rb
# Running tests:

F

Finished tests in 0.000601s, 1665.0543 tests/s, 1665.0543 assertions/s.

  1) Failure:
test_our_test_framework_can_fail(TestDevelopmentMethodology) [test/unit/development_methodology_test.rb:5]:
Failed assertion, no message given.

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

I'll swiftly rewrite my test now that I know everything is working. I'm going to put a condition that a Development Methodology must contain a name.

require 'test_helper'

class TestDevelopmentMethodology < MiniTest::Unit::TestCase
  def test_development_methodology_has_name
    development_methodology = DevelopmentMethodology.new
    assert !development_methodology.save
  end
end

And run it

[]$ ruby -Itest test/unit=development_methodology_test.rb

# Running tests:

E

Finished tests in 0.032036s, 31.2147 tests/s, 0.0000 assertions/s.

  1) Error:
test_development_methodology_has_name(TestDevelopmentMethodology):
ActiveRecord::StatementInvalid: Could not find table 'development_methodologies'

It errors! But of course it does - we haven't run a migration yet. Let's do that and at the same time prepare our test database

$ rake db:migrate
$ rake db:test:load

Run our test again and you should get a failing test

[]$ ruby -Itest test/unit=development_methodology_test.rb

# Running tests:

E

Finished tests in 0.032036s, 31.2147 tests/s, 0.0000 assertions/s.

  1) Failure:
test_development_methodology_has_name(TestDevelopmentMethodology) [test/unit/development_methodology_test.rb:5]: Failed assertion, no message given.

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

Refactor our test

The first thing I'm going to do is refactor my test - because MiniTest includes both assert and refute statements, I think my test could be more readable if I write it like this (of course, running the test again produces a failed test as above):

require 'test_helper'

class TestDevelopmentMethodology < MiniTest::Unit::TestCase
  def test_development_methodology_has_name
    development_methodology = DevelopmentMethodology.new
    refute development_methodology.save
  end
end

Make the test pass

Making this test pass is simple - we just have to validate the presence of name. Edit app/models/development_methodology.rb and add in our validates

class DevelopmentMethodology < ActiveRecord::Base
  attr_accessible :description, :name
  validates_presence_of :name
end

and now our test passes

$ ruby -Itest test/unit=development_methodology_test.rb
Run options: --seed 20660

# Running tests:

.

Finished tests in 0.139823s, 7.1519 tests/s, 7.1519 assertions/s.

1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

Make it purty

Now MiniTest comes with a lot built in - want your output to be in lovely colours - no problem - just run your tests like this and witness the beautiful and fabulous tests:

$ ruby -rminitest/pride -Itest test/unit=development_methodology_test.rb

Spec

A big plus point for MiniTest is the inclusion of spec by default. Watch what happens when we change our test to look like this:

require 'test_helper'

describe DevelopmentMethodology do
  it "must have a name" do
    development_methodology = DevelopmentMethodology.new
    development_methodology.save.must_equal false
  end

end

If you re-run your tests now, you get passing tests (obviously, because we've simply rewritten a passing test), but you've used some nice contextual RSpec like syntax all rolled up in MiniTest

That's good for today

I think that's enough of an introduction to using MiniTest with Rails. Hopefully, you've got some code to get you going so you can jump right in an explore MiniTest.

Friday, 14 September 2012

Javascript - Objects by ref

If any language should have been name after a snake, Javascript should have. It's a slippery little thing I tell you. It slithers and slides and wraps around you. And you have to work like a snake charmer to coax it out of its basket and make it play nicely without biting you.

Take, for example the simple idea of passing a variable by ref or by val. Javascript's snakey little implementation means that if you are passing a variable then you'll never pass it by ref. However if you are passing an object, then, hey presto, by ref it is. Bear witness:

var globalVar;
      var anObj = function() {
        this.value = "default value";
      }

      function changeValue(arg){
        arg.value = "Changed by function";
      }

      function changeUp(arg) {
        arg = "Changed";
      }


      globalVar = "global";
      console.log(globalVar);
      changeUp(globalVar);
      console.log(globalVar);

      var myObj = new anObj();
      console.log(myObj.value);
      changeValue(myObj);
      console.log(myObj.value);

Yep, slap that into some html and run it with your Chrome developer console up and about and you will see something like this:

global
global
default value
Changed by function

Yes sir! that Javascript. She's a tricky little snake of a language. Nothing at all like Python. Nothing at all like Asp. Nope, it's in a league of its own.

Tuesday, 4 September 2012

Ruby frameworks, Rails and Padrino

Some thoughts on the Padrino and Rails. For the past few weeks, I've been working on a small project that is using Padrino rather than Rails. The interesting thing was that the decision for the technology was based on the idea that the project was only going to have a few objects; at most five or six and as such, didn't need something as large, complex or weighty as Rails. However, something as barebones as Sinatra would not allow for some of the more rapid application development that you get from some of the baked in goodness of Rails - things like Sessions, Flash, Form helpers and generators all speed up development fairly considerably. With that in mind, Padrino was the framework of choice.

Now Padrino is interesting. It's a great little framework, but, the temptation is to look at it's relative light-weightedness in comparison to Rails and think it will require less learning time or up-front knowledge for someone with little experience of the framework or of something like Rails. This is really a false economy. I would, in fact, say that for a beginner, Rails, not Padrino, is the sensible choice. Rails has excellent documentation right out of the gate, Padrino - well the documentation is just okay. It's enough for a seasoned developer to use, but unless you are already familiar with Rails, you might find yourself floundering a bit trying to figure out how to do something relatively simple.

The other area in which Rails really excells is in the sensible defaults - Padrino, in a way, requires you to really know your technology up front. Padrino is less opinionated than Rails and allows you to plug in various different components to pretty much any part of the system, even coding your own if you fancy. However, this kind of flexibility comes at a price - you need to know what you're going to use up front - Datamapper? ActiveRecord? Sequel? With Rails, the decision has been made for you - ActiveRecord. No faffing about with analysis paralysis. On the other hand, this kind of agnostic framework is good for those with specific requirements to use the non-defaults.

Where Padrino really shines in my opinion, is in the admin support. Generating an admin backend to your app is so simple. Granted with Rails you can use ActiveAdmin or something, but really, having this kind of CRUD baked in to a framework is awesome - one of the things, incidentally, that I love about Django.

So, when should you use Padrino? Well, my advice is, when you already know Rails and you want a framework that's a little bit smaller. But, heed this will if you are new to Ruby based web frameworks - learn Rails first.

Monday, 27 August 2012

Rails 3.2 Could not find a JavaScript runtime execjs

Running a fresh copy of Linux Mint and Rails lets you generate a new project with no problems, but you might start to hit issues as soon as you start trying to generate some scaffolding. So for example, if you try
rails g scaffold User name:string email:string
You'll get something like this:
/home/x/.rvm/gems/ruby-1.9.3-p194@rails3.2/gems/execjs-1.4.0/lib/execjs/runtimes.rb:51 in 'autodetect': Could not find a JavaScript runtime.
It will also tell you to visit https://github.com/sstephenson/execjs to see a list of available runtimes. Don't be shy now, head over there and take a look. Or, if you just want to hack it, add the following to your Gemfile:
gem 'therubyracer'
Run your bundle update and you should be good to go.

Thursday, 23 August 2012

What playing in bands taught me about Startups

When I was in university, I thought my band was going to be the next big stadium rock band. We took our music seriously. We played. A lot. We gigged. A bit. We sucked. Big time. Even though, as far as we were concerned, we were destined for fame.

I wish I could point to a single event that brought me to my senses, but really it was just a gradual realisation that I wasn't as good as I thought I was and that, in fact, getting to be "Rolling Stones" famous, was partially luck. I remember once reading an interview with Mark Knopfler. Some fan-boy was asking him about a trip to South America or something saying how Mark probably taught the locals a thing or two about guitar playing. Knopfler replied something to the extent of "naa man, those guys down there can play their ernie balls off. They put me to shame. I'm just a schmuck who got lucky". Full kudos to the man. Humble and self-realised all in one.

Anyway, after a while I stopped being so pissed that my raw talent was going unnoticed, checked a little bit of my ego at the door and stopped trying to put a band together. I just started playing for fun. Now I tinker. I like to play music, and I'm reasonably good for an amateur, but I'm just happy that I can sit in my living room and noodle away in the corner without the cat shrieking or my family skulking off into another room because the sound is so horrid. Heck, the last band I was in sort of fizzled out. Our guitar player left because we weren't goth enough, and our drummer left because he wanted to play covers on cruise ships for money. Seriously, you can't make that stuff up.

Startups are the same. Lookit:
We are looking for someone who has a burning passion, someone who wants to create something unique & exciting. Must be committed! No time-wasters
Seriously, adverts for bands and adverts for startups are practically the same, except in one they idolise QOTSA and in the other they idolise QUORA.

Adverts for bands always want "the next Steve Via" or "the next Dave Grohl". You have to "have a rockstar vibe and image, be ungodly tallented on multiple instruments and be available for rehearsal every minute because we have gigs coming up". Bullshit. You're playing a shitty gig in a shitty dive in two month's time and it won't matter if your guitarist can shred on not because by the time your slot comes around, eveyone will have left the bar or be so blind drunk they won't notice. Couple that with the fact that pretty much every song you've written is just a I-IV-V progression and really you just need someone to play a few notes from the minor pentatonic scale over the bridge section as a solo and you might as well just grab he nearest person you know, give them an old epiphone and plug them in through an auto-arpegiator pedal. It will sound fine.

Adverts for startups always want "rockstar ninja coders who can work with ruby, php, python, java, clojure have a deep knowledge of javascript (sans framework) and be able to do big data with neo4j, have mad skills in linux admin and be able to design compelling front ends". Bullshit. If anyone actually has all those skills to a half reasonable level, they aren't going to wasting their time working for "equity", they'll get a real high-paying job at an established company. Or they'll freelance. Be honest, you need an mvp and the only reason you've put in every major buzzworthy language is because you don't, or can't code. You're only going to need 2 lines of jquery on one screen, and your app is pretty much just a mash-up of apis that connect to facebook and twitter in the hopes that it goes viral. Your data entry is simple crud, "rails g scaffold" will do just fine for pretty much every screen and you're just going to bung on Twitter Bootstrap with maybe a different colour navbar. Monkeys from college can code this up for you as long as they can type "gem install".

Don't be fooled by the play to your ego that always comes towards the end of the advert:
This position entails much more than just being a coder/lead guitarst; you will be an integral part of the company/band with input in major decisions/song writing and the direction of the company/band.
In other words, the startup has no idea what they are building or how they will make money. The band has no songs of any substance written. The startup hopes that you have some great ideas and enough social clout to get some buzz going. The band hopes you have a string of original tunes written, recorded and ready to present to your contact in A&R at Sony.

There are some, though, that want honesty, that aren't looking for some pie-in-the-sky bullshit. The last time I was looking for a few people to jam with now and then, I put out an ad that went:
Part-timer with no aspirations of making it big looking for other musicians who just want to jam now and then. We aren't going to be big, but we are going to have a good time.


I got more responses than the new girl on the dating site.

Imagine if startups started advertising like this.
3 guys with macbooks who like to faff about with ruby on rails and nodejs and put up lolcat clones looking for someone to tweak the api calls a bit.
For an excellent, though very long read on startups read Don't waste your time in crappy startup jobs Drop me a line if you want to code, or jam.

Tuesday, 21 August 2012

Triple boot Linux, Windows 7 and Windows 8 RTM

I wanted to have a triple boot computer - why? don't ask me why! Oh, ok, I'll tell you - I needed Windows 7 for some current work and didn't want to mess up the install. I wanted to install Windows 8 so I could play with the metro style app development that I've seen floating around and of course, I like my Linux system for my ruby web development.

So - here's the rough steps without a specific walk through of each one, except for reinstalling grub, which is really the crucial step to getting everything to hum and purr along nicely. The caveat is that this worked for me, on my system, it might not work on yours - so take precautions, backup, verify backup, store a backup off-site - you know the drill, I shouldn't need to tell you.:

1) Install Windows 7 Easy enough, follow the prompts and pop Windows 7 on your machine.

2) Install Linux Choose your flavour - I've got Mint up and running, but go for Ubuntu if you prefer. Actually, go for pretty much whatever you want. Ubuntu and Mint will give you a nice trouble-free install of Grub to dual boot your system. It should work out of the box.

3) Create a VHD in Windows 7 and use that space to install Windows 8. Check out Scott Hanselman's great blog posts on this because it takes you through in detail what you need to do. Pay attention, because it's subtle (How to guide to installing and booting windows 8 consumer preview off a VHD and Guide to booting windows 8 developer preview of a VHD)

4) Boot up into Windows 8. Crap your pants a little as you notice the Windows 8 boot loader has made your Linux install disappear.

5) Boot to Linux with a live CD and re-install Grub manually. This is fairly simple - once booted, bring up a terminal and do the following (obviously, you need to know your partition number that you've got your linux install on - mine's sda6 - I have sda1 and sda2 as system recovery and windows recovery, sda3 as my Windows install, sda4 is a logical partition, sda5 is swap, sda6 is my actual Linux mint):
sudo mount /dev/sda6 /mnt
sudo grub-install -root-directory=/mnt/ /dev/sda
Note that the second line has the number left off the "sda" on purpose. PAY ATTENTION!

6) Re-boot - you should have options for Linux and Windows 7 again. On my system, selecting Windows 7 takes me to the Windows 8 bootloader from whence I can choose either Windows 7 or Windows 8 for boot.

Now this isn't perfect, because I have 2 boot menus, but you know what? It will do for now.

Monday, 13 August 2012

Generate an absolute URL in padrino

Sometimes, you just need that absolute URL. Padrino gives you a great little helper to create your urls in th form of url_for. Unfortunately, Padrino's documentation seems to be written from the point of view of someone who is intimately familiar with Rails, which means the total noob trying to get into Padrino without any Rails experience can be left a little flummoxed. Anyway, it is important to realise that Padrino has Sinatra as its base and you can tap into all that goodness that Sinatra offers. Absolute urls are as simple as:
<%= uri url(:controller, :action, :param=>value) %>
Lovely.

Thursday, 9 August 2012

Ruby LoadError: cannot load such file

So, you've set yourself up a lovely new app using, for example, Sinatra, and you're really chaffing at the bit to write some lovely code. But you keep getting bit by this:
LoadError: cannot load such file -- sweetsweetcode
You double check your config.ru but it is pretty standard stuff:
require 'sweetsweetcode'
run Sinatra::Application
What can be wrong? Please tell me oh gods of Ruby. Is it Passenger? Is it Rack? Have I uncovered a great big bug in Ruby itself? Naaaa! Of course not you fool, it's just that you're on the very latest version of Ruby, probably 1.9.3 or something and the load path no longer includes the current path. So to fix it, just do this:
require './sweetsweetcode'
run Sinatra::Application
And you should be singing again.

Wednesday, 8 August 2012

Adding an item to Linux Mint Cinnamon Menu

Last time I took you through installing Sublime Text 2 on Linux Mint. The trouble with doing the install the manual way as I showed and not using sudo apt-get is that you don't get the neat integration into the operating system so you wont find Sublime Text in your Menu and if you search it wont be there yet. Right click on the "Menu" in the bottom left and choose "Edit Menu". You should have something that looks like this:
Excellent. On my install, Programming was not yet ticked, so I clicked the checkbox so that the Programming section would show up in my Applications menu. Then on the left hand side, you need to click Programming, or whichever other category you want to put Sublime Text into and then on the right, click the "New Item" and fill it in as follows:
If you followed along when I installed Sublime Text, you aliased subl to launch Sublime Text. Clicking where the icon is will let you choose the icon location. I used the 48x48 icon in the Sublime Text 2 directory. Finally click the "show" text box against the new entry and you should be good to go. Sublime Text 2 will now show up in your menu under the Programming category and also if you start typing Sublime Text 2 in the search box.

Monday, 6 August 2012

Padrino, Datamapper, Rake, Uninitialized Constant

So, perhaps you've set up a fancy application using padrino, datamapper and sqlite and you are going great guns until
padrino rake dm:migrate
=> Executing Rake dm:migrate ...

rake aborted!
uninitialized constant Text
Or something similar - the datatype is probably not too important. The solution is to edit your migration and put the datatype into quotes....like this:
column :description, "TEXT"
There seems to be a bug with the use of datamapper and the migration. I'm not sure where the bug is, but this fixes it!

Friday, 3 August 2012

Installing Sublime Text 2 on Linux Mint

So, continuing on from installing RVM on Linux Mint and installing Ruby on Rails on Linux Mint, I want to give a brief rundown on installing Sublime Text 2 on Linux Mint, though in fact, this will work for pretty much any Linux version, so if you're running Ubuntu it will work as well. If you aren't using Sublime Text 2, I suggest you download it and give it a go - it's an awesome editor, especially for Rails and Python development, bringing a Textmate elegance to Linux. It's cross platform too, so if you are jumping between OSX, Linux and Windows, it makes the perfect companion giving you a consistent interface across the various OSs. Don't trust me? Well take a look at what others think about it So, there are two routes here - you can install using the traditional apt-get on Mint. You'll have to add a repository. That's not really my preferred method though. It takes too long to get releases through to the repository so I like to do a manual install. Don't worry, this isn't complex. First you'll need to download Sublime Text 2 - grab it with wget or just go to the website and download it.
tar -jxvf Sublime\ Text\ 2.0.1.tar.bz2
Your filename might be different if you've got the 64bit version, or if the Sublime text version has incremented. Now you've got a Sublime Text 2 directory with everything you need in it. Next, I like to move it into /opt but feel free to put it anywhere that you normally install additional programs; maybe somewhere in your home directory. Anyway I do:
sudo mv Sublime\ Text\ 2 /opt
Last, but not least, I create a symlink
sudo ln -s /opt/Sublime\ Text\ 2/sublime_text /usr/bin/subl
You should already have /usr/bin in your path so now you can just run
subl
from your terminal to get sublime text to startup. Finally, you should look at Michael Hartl's tutorial on setting up the various packages and plugins to ease Rails development with Sublime Text 2

Thursday, 2 August 2012

Installing Rails on Linux Mint 13 with RVM and gemsets

Last time I did a quick RVM install guide for Linux Mint. This time I'm going to finish up by installing rails so we can rock some new development work. Nothing like a clean and humming system I tell you. Let's begin by making sure we have git - we are going to be using it anyway. Fire up your terminal (Ctrl-Alt-T) and type
sudo apt-get install git
Great - version control level unlocked. We should have rubygems installed already (if you followed along with the RVM install then this is all taken care of). Now, to make sure RVM functions well, see this https://rvm.io/integration/gnome-terminal/. Or, if you prefer, just move the commands from .bash_login to .bash_profile. As I understand it, and I'm no Linux guru, .bash_login doesn't run if .bash_profile is present. I'm going to create a gemset to install rails 3, just for fun...and just in case I want to go back and work on some legacy apps.
rvm gemset create rails3.2
And set it so it is the default gemset with ruby 1.9.3
rvm use 1.9.3@rails3.2 --default
Note, your ruby might be different - run
rvm list
to find which ruby you have installed and which is current and which is default. If you've started fresh with Mint like I did, then you should be good to go with my command above. We need a few dependencies - if you didn't install these when you put RVM together then do them now
sudo apt-get install build-essential openssl libreadline6 libreadline6-dev \
curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 \
libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison  \
subversion
Now, install rails with
gem install rails

Tuesday, 31 July 2012

Installing RVM on Linux Mint 13

Linux Mint has captured my imagination recently, and of course a fresh install means getting my dev environment up and running again. I'm using the cinnamon version and so far things are going well. Everything on my laptop is just working; suspend, all the various function keys. Support out of the box is good. I'm impressed. The experience is soooo much better than the last time I tried a more full featured distro and things got so bad with video drivers crashing and causing my fan to spin up constantly that I ended up going totally minimal with Arch and just a command line. I like arch, but I thought I would give Mint a go. So, now we need to get Ruby, RVM and Rails on the go so we can do some web development. Let's start with RVM. Next time I'll take a crack at installing Rails on Mint First things first - we need curl. My install didn't have it so.....fire up the terminal with Ctrl-Alt-T and type the following
sudo apt-get install curl
Next up, install RVM
curl -L https://get.rvm.io | bash -s stable --ruby 
Which all went pretty well. At the end of the install, simply running
source ~/.rvm/scripts/rvm 
in my open terminal session brought everything up to snuff. Now I'm going to install a few dependencies
rvm requirements 
to check what you need on your system. Mine needed the following command to get up to speed.
sudo apt-get install build-essential openssl libreadline6 libreadline6-dev \
curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 \
libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison  \
subversion
And annoyingly I had to
rvm reinstall 1.9.3
because it was already installed but without doing the reinstall all sorts of nasty errors would occur when trying to install gems later on. Next a quick verification:
which ruby
>> /home/rubyflewtoo/.rvm/bin/ruby

ruby -v
>>ruby 1.9.3p194
I didn't have a system ruby installed given my version of Linux Mint was fresh off the boat, but if you did and you want to default to ruby 1.9.3 (which you should) then you could run
rvm use 1.9.3 --default

Friday, 20 July 2012

Jekyll and ruby 1.9.3 site not regenerating

If you are trying to compile a site with Jekyll and ruby 1.9.3 and you have some dodgy yaml front matter in one of your posts, your site just won't regenerate. Step 1 is to edit your _config.yaml and set auto: false. If you leave auto:true then it won't report the errors at all. With that, if you run your jekyll --server command again, you could get an error to the effect of "did not find expected key while parsing a block mapping at line" blah blah blah. The error isn't particularly useful. However, help is at hand - see this pull request which you can manually apply to your gem if you want and you'll start to get meaningful error messages again. I monkey patched mine by editing my lib/jekyll/post.rb file to include the pull request's code. I guess you could use RVM and use an older ruby version, but this did the job for me

Creating flash messages bootstrap style

I'm on a twitter bootstrap binge at the moment, it fills my soul with glee to start a new project with a base template that looks better than the usual dog's breakfast. Anyway, there are days when you just need a piece of code to blast in to your templates so that you can get on with your work. This is one of those and slapping the tremendous bootstrap success, warning and info messages into our normal flash message stylings is just what the doctor ordered. Here then, for your delectation, a small snippet of code to pop into your application layout in place of your usual flash message code that will style things up the bootstrap way. If you prefer, pull this out into a helper.....if you think that's the rails way. Personally, for small projects, I don't bother.

Thursday, 19 July 2012

Add css class to your label form helpers

Say, for example, you are using Twitter Bootstrap to style up a quick rails app and you want to throw in a label tag with the class set to "control-label" just like the bootstrap guys do.....how do you do it? And more importantly, since you don't want to specify the text of the label, how do you accomplish that? Fear not intrepid young but soon to be rails guru, behold the truth:

Tuesday, 17 July 2012

Nginx and Rails into development mode

If you are running a rails app with nginx serving it up and you want to put the whole shebang into development mode, open up your nginx.conf file and in the server section, add the following line: rails_env development; Remember though, it takes a ton more resource to do this so remove the line when you're done. Part of the fun of doing this is if you are hacking away on a project and you want to skip the precompiling of assets and such.

Rails and rake error - could not fined a Javascript runtime

If you are running into this little bug when running either rake or rails generate task then you can usually solve it pretty quickly by adding the following two gems into your Gemfile: gem 'execjs' gem 'therubyracer' For rails noobs, Gemfile is in your application root.

Monday, 16 July 2012

Fun with ruby arrays - update and insert

Here's a fun thing with ruby arrays - follow along in irb: using "..." and changing elements at the same time will update the first element specified and insert a new element after that element at the same time. fun :)

Sunday, 15 July 2012

Rake db:migrate error undefined local variable or method

If you are running rake db:migrate and hit an error that says something like Undefined local variable or method 'variable_name' for then you've probably left off a ":" on one of your variables in your migration.

Friday, 13 July 2012

Redirect www to non www nginx

nginx is great - here's a quick tip if you are serving up a Sinatra app using it....well actually any app I guess. Redirecting a www based domain to a non-www based or naked domain is pretty easy - in the nginx conf file, you'll need something like this:

Installing a gem with no documentation

Often you will want to install a gem on your local system or server, but you don't require the documentation, you want to leave it out. This not only speeds up the install, but saves some space on your machine. Here's the script to run from the command line if, for example you were installing the rack_csrf gem: The reason for both "no-ri" and "no-rdoc" is because there are actually two types of documentation being installed - the RDoc is essentially embedded documentation generator for the Ruby language. It will analyze source code and create the documentation. the Ruby ri files are to all intents and purposes Ruby's version of man pages which give you documentation from the command line.