Gem-ified WBXML4R

Posted by tom May 21st, 2008

I’ve had a lot of requests for the sourcecode for WXBML4R – a Ruby extension which allows you to convert from WBXML to XML and vice-versa. So far I’ve sent the code to people who asked, but now I’ve gem-ified the code and with the use of a gem, it’ll be a lot easier! Hopefully I’ll soon find the time to create a Rubyforge page for it and put it on there.

UPDATE: I’ve just asked for the RubyForge project, once that’s approved I’ll publish the gem there.

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