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).
