Ruby Qualification Test

Posted by tom May 21st, 2008

Recently, as part of an interview, I’ve been asked to make the following test (in Ruby):

1) Write a program, which asks the user for a URI/URL. The program should then go off, and fetch the webpage which is on that URI/URL. You’re not allowed to use any existing HTTP library (ie use a socket connection yourself). 2) Extend the program so that it loops, until the user enter’s a q (for the URI). 3) Extend the program so that it displays the headers, separated from the body. The headers should be separated in key – value pairs.

I’ve perceived this as a very simple test, which hardly requires OOP. I would use OOP if it would simplify the solution or when it would contribute to the re-use of components. As this was a test, it’s inherently a one-off, therefor no OOP in my opinion. The testers felt otherwise, so I rewrote my entire solution as follows.


# 
#  test.rb
#  degrunt.net
#  
#  Created by Tom de Grunt on 2008-05-21.
#  Copyright 2008 degrunt.net. All rights reserved.
# 

require 'uri'
require 'socket'

class Request

  include Socket::Constants

  def initialize( uri )
    begin
      @uri = URI.parse(uri)
    rescue URI::InvalidURIError => e
      raise "Please enter a valid URI" 
    end
  end

  def get
    socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
    sockaddr = Socket.pack_sockaddr_in( 80, @uri.host )
    socket.connect( sockaddr )
    puts "Path: #{@uri.path || '/'}" 
    socket.write( "GET #{@uri.path || '/'} HTTP/1.0\r\n\r\n" )
    socket.read
  end

end

class Response

  def initialize( text )
    @text = text

    headers,@body = text.split(/\r\n\r\n/)
    headers = headers.split(/\r\n/)
    @status_line = headers.shift

    @headers = {}
    headers.each do |h|
      kv = h.split(/: /)
      @headers[kv[0]] = kv[1]
    end
  end

  def to_s
    result = "" 
    @headers.each do |k,v|
      result << "#{k} - #{v}\n" 
    end
    result << @body
    result
  end

end

# ========
# = Main =
# ========
begin
  puts "Please enter a URI (press Q to quit): " 
  uri_str = gets.strip.downcase
  unless uri_str == 'q'
    request = Request.new(uri_str)
    puts Response.new(request.get)
  end
rescue Exception => e
  puts "An error occurred: #{e}" 
end until uri_str == 'q'

Please share your thought on whether using OOP or not is a good idea and whether this test successfully tests one’s qualifications as a Ruby programmer.

On the other hand, I can tell you that I’ve written Ruby Extensions (three by now) using Ruby and C-code, I wrote a Radiant CMS plugin and wrote a couple of Ruby on Rails websites in my spare time. Professionally I work on an extensive Ruby on Rails project, which tests the boundaries of Rails (if I may say so).

Installing MySQL gem on Mac OSX 10.5 (Leopard)

Posted by tom January 15th, 2008

sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5

Trying to write a Rails ConnectionAdapter

Posted by tom January 6th, 2008

Today I’ve started with trying to write a Rails Connection Adapter for IBM U2 (UniData/UniVerse). There’s very little documentation available, only a couple of examples.

PostgreSQL on Mac OSX 10.5

Posted by tom November 10th, 2007

I’ve downloaded PosgreSQL from PostgreSQL for Mac and installed it, immediately after the server runs. From the diskimage I got the folders where the terminal binaries are installed (the GUI tools which come with the package don’t work for me) and it all worked. That saves a lot of compilation time!

Using Ruby on Rails with PostgreSQL is fairly simple, just install the ruby-postgres gem (gem install ruby-postgres) and have your database.yml represent something like:

development:
  adapter: postgresql
  database: my_development
  username: tdegrunt
  password:
  encoding: utf8

Ruby Xerces, Xalan and XQilla

Posted by tom September 27th, 2007

Ruby is badly in need of proper XML extensions for Xerces, Xalan and XQilla. That way it is easy do XML parsing and processing and transformation, one step closer to acts_as_enterprisey.

I’ve seen a couple of people suggesting the use of SWIG for creating these kind of extensions. I managed to compile the lot (Xerces, Xalan and XQilla) on Mac OSX (10.5 I might add), but using SWIG is beyond me (for now).

Generating EAN13 Barcodes with Rails

Posted by tom June 3rd, 2007

Today I wrote code which generates EAN-13 Barcodes from Ruby/Rails, with the help of RMagick and ImageMagick. There already was a barcode-gem but that just generated Code39 Barcodes. Based on the code in that gem, better said: following the conventions in that code I created a class which now is capable of generating EAN-13 PNG images:

EAN 13

Why do I do such things? Well, it’s part of my new pet project: Barcodes on Demand

Engines and sub-apps

Posted by tom February 25th, 2007

Just came across this article by James W. Long. I think the statement he’s making is a very valuable one: Rails DOES need (and deserve) something better than Engines. Not that engines are bad, on the contrary, it’s a good step in the right direction. And no, Engines are not Evil.

WBXML4R: WBXML for Ruby

Posted by tom February 4th, 2007

Today I’ve created my very first Ruby Extension: WBXML4R. It’s a pretty simple extension, but I needed it very badly. It translates WAP Binary XML to XML and back, now if somebody can explain me how to wrap this in a gem I’d appreciate it. It uses wbxml2-0.9.2 available from here. If you want it drop me a mail.

The idea for it’s use is simple: I want to write a small Ruby server which will allow my P990 to sync with it.

Read the rest of this entry