I’m experimenting with comparative differences in Python and Ruby. Here is an example from each language, designed to do exactly the same thing: go and get a copy of “A Comedy of Errors” from Gutenberg, and dump it to the console. Not too useful, but interesting from the perspective of seeing how the two languages handle interacting with the web (the one thing they both claim to do extremely well).

First, the ruby version:

module HTTP_Examples
  require 'net/http'
  require 'uri'

  class SimpleTesting
    def initialize()
    end

    def fetch(uri_str, limit = 10)
      raise ArgumentError, 'HTTP redirect too deep' if limit == 0

      response = Net::HTTP.get_response(URI.parse(uri_str))
      case response
        when Net::HTTPSuccess     then response
        when Net::HTTPRedirection then fetch(response['location'], limit - 1)
        else response.error!
      end
    end
  end

  test = SimpleTesting.new()

  response = test.fetch('http://www.gutenberg.org/cache/epub/2239/pg2239.txt')
  print response.body
end

The second version is Python:

from urllib2 import URLError, urlopen, Request

class SimpleTesting(object):

    def fetch(self, uri_str, limit=10):
        if limit == 0:
            raise ValueError,'HTTP redirect too deep'
        try:
            response = urlopen(Request(uri_str))
        except URLError, e:
            if hasattr(e, 'code'):
                if e.code == 301:
                    print e.code, e.reason
                    self.fetch('http://www.gutenberg.org/')
        else: #everything is fine
            return response

def main():
    test = SimpleTesting()
    response = test.fetch('http://www.gutenberg.org/cache/epub/2239/pg2239.txt')
    print response.read()

if __name__ == "__main__":
    main()

In general, the two examples aren’t all that starkly different. But there are some significant divergences.

First, the Ruby version makes library calls in much the same way as Perl does, while the Python version conforms more to the Java model.

Second, Python doesn’t seem to have an analogy to CASE, so you have to wrap everything in an exception handler. But with HTTP, some of the responses aren’t really “exceptions” so much as simply higher-level responses than 200. Why?

Third, is that Python seems to be able to deal with redirection dynamically, while Ruby needs to recursively iterate through each new location. Why?

Lastly, Ruby is much easier on the eyes, and easier on the brain, I think. Aside from the ugly Perl-like library calls, there’s no need to define and then superflously call any of that junk called “main” (as is a convention in java as well, I believe), in Ruby. Again, why?

These, and many other questions, will be addressed as my exploration continues…