Main Content

Ruby off the Rails?

Archive - Originally posted on "The Horse's Mouth" - 2011-09-06 22:31:35 - Graham Ellis

Time was ... "if it's Ruby it must be Rails". The Ruby on Rails framework was the initial killer application that brought the Ruby language to the attention of many, and was so prevelant that it masked other excellent uses. So I'm delighted to see significant other uses of Ruby growing in addition to its use in Rails. Ruby is an excellent, and still underrated, "scripting" language, taking the eclectic best principles from Perl 5 and adding a true underlying Object Oriented philospohy and foundations.

I'm giving a Ruby course this week; I will be running a day to introduce Rails on Friday, but up to that point we're looking at the language - for delegates who are new to programming, rather than for programmers converting from something else. It's our Learning to program in Ruby course.

For readers who may be familiar with programming in other languages, may I present an elegant script which I wrote at the end of yesterday - [here]. I've taken all the records in a data file, each of which contains data about a UK railway station, and created an object from each. I've then enquired of the objects looking for stations where traffic has grown almost five times in six years, and reported on that selected few. That's the overview ... now for the code ...

Open the file of data, and initialiase an "array" to hold each station:

  fh = File.new "railstats.xyz"
  stns = []


Read each station into the array, converting the data on each line from a string of text to a format that's easily useable:

  while (lyne = fh.gets)
    stns.push Station.new(lyne)
  end


Loop through each of the places where there's a station, reporting on the growth if it's between 4.5 and 5 times:

  for place in stns
    growth = place.getgrowth
    if growth > 4.5 and growth < 5.0
      puts "Growth #{growth} at #{place.getname}"
    end
  end


Of course, much of the work that's done here is in the piece of code that defines a Station, how it works and what we can do with it. For the purposes of this demonstration I included the definition in the same program file (it means that the delagates can see it all in one window, and that you can download it all in a single file) ... for a live and developing suite of applications, I would share the station definition between programs by wrining it in a separate file and then calling it up with a require statement.

Anyway - the definintion of a "Station":

  class Station
    def initialize(record_text)
      @fdc, @tlc, @postcode, @gridref,
      @lati, @longi, @name, @t2005,
      @t2006, @t2007, @t2008,
      @t2009, @t2010 = record_text.chomp.split "\t"
    end
    def getgrowth
      return 1.0 if @t2005 == "NULL" or @t2010 == "NULL"
      @t2010.to_f / @t2005.to_f
    end
    def getname
      return @name
    end
  end


There's a great deal more that I could do there, and some design decisions made ... I've elected to name each element from each line and to store them in separate variables not an array, but I've elected to store them all as strings rather than make conversions to other types. I've decided to leave the logic to work out whether or not I can calculate a growth factor until the code is asked for such a factor rather than doing so as soon as each Station is set up, and I've decided that if I can't calculate a growth factor, I'll treat the station as if it had neither growth nor a loss in traffic. The beauty of the structure that Ruby has let me employ is that all these detailed decisions can be left up to the station 'expert' and hidden in this class definition. The person calling the code shown earlier just need to know what questions to ask and how to handle the answers. This 'hidden within' approach is known as encapsulation if you would like a posh word for it.

You can download the data (it's extracted from public data provided by the Office of the Rail Regulator and the Department for Transport amongst others) from [here]. Output looks like this:

  munchkin:rs grahamellis$ ruby thirdrail
  Growth 4.84424038039829 at Bradford Forster Square
  Growth 4.69588971475764 at London Fields
  Growth 4.88378896251115 at Hackney Wick
  Growth 4.62891340332681 at Maghull
  Growth 4.91176855609373 at South Tottenham
  Growth 4.60778231652162 at West Hampstead Thameslink
  Growth 4.72221717401181 at Brondesbury Park
  Growth 4.725 at Havenhouse
  Growth 4.97251091015432 at Ore
  Growth 4.64773309666371 at Worcester Foregate Street
  munchkin:rs grahamellis$


... none of which I have any photos of to illustrate the article ...

My subject line asks "Ruby off the Rails?". Most certainly it is not. It's an excellent language, and this week's a real pleasure letting me introduce programming through Ruby to a group of delegates on our course.