Saturday, February 18, 2012

Perl, Java, Ruby

Well, I realized the Pine Flat Road Race was tomorrow (Sunday) not today (Saturday) and so, had I rested today, I probably could have gone. Ah, well. I have a rule that I need to do a hard group ride before I even think about racing, and I haven't yet done so this year, or even towards the end of last year. No, the Friday Noon Ride is not a "hard group ride".... nor is Wednesday. Only Tue and Thu come close to qualifying. So it probably wouldn't have been prudent trying to mix it up at Pine Flat, anyway. But on the positive side, that's 6-7 hours I will not be spending in a car, and more time I won't spend in a smelly motel room, more time to devote to my coding project.

On Facebook, it was recommended I look at Ruby. This was an obvious thing to do, since it is what Strava uses for its API example. However, I had gravitated towards Java because with Java I knew I could generate an Android app. All it takes is a bit of Googling to note that Android apps can be written in Ruby as well, but the most popular language for Android apps is clearly Java.

Ruby, or more particularly Ruby On Rails, is gaining popularity for serving web pages. I knew virtually nothing about Ruby until today, but even with a brain severely impared from the accumulated fatigue of four consecutive days totalling over 200 miles of hard bike riding (including today's semi-epic), I've found it surprisingly quick to pick up. The main web site has good documentation, including some nice tutorials. What I like about what I see there is it combines the ease of data handling (implicit typing, automatic type conversion, automatic array allocation, easy-to-use hash tables, etc) of Perl with a strong object orientation which I've read is similar to SmallTalk, an ancient rarely used language.

A simple example: converting a data structure to JSON format for communication with the Strava API.

With Perl, I whipped together a "Strava_to_CSV" script using the JSON library. Here was how I decoded the JSON stream:

my $json = JSON::PP->new;
my $data = $json->decode($s);
This gives me a reference to a hash table with the keys the field names, the values the field values. This is great, minimal fuss.

With Java, I've been using the Google-GSON library, which has been claimed to be relatively easy to use. However, it's much more work than the Perl library. With GSON, I need to set up a class with variables with the same names as the fields in the JSON stream, with types correctly set up for each field. So with easy API command returning its own unique JSON structure, that means setting up a class specific to each API command (or class of API commands: some may share the same class). It's not a huge roadblock, but is a hassle and adds lines of code, and with that, opportunities for errors. And with Strava something of a moving target, it increases the maintenance costs of any code I put out there.
So onto Ruby. There's a nice JSON library for Ruby which seems to work much like the Perl one. Here's a super-trivial example, where I generate an array in Ruby, encode it as a JSON string, then I both encode and decode it:

#! /usr/bin/ruby
require 'json'
a = [1, 2, 3, 4, 5, 6]
puts a
puts JSON.generate a
puts JSON.parse JSON.generate a

The output is:

1
2
3
4
5
6
[1,2,3,4,5,6]
1
2
3
4
5
6

The biggest hassle with this was getting the JSON library installed. I tried using "gem", but that didn't seem to work, so I used "apt-get ruby-json", and that did the trick. If I can get this sort of thing running in just a few minutes, that's a good sign.

Interacting with web pages is another issue. With Java, the following line is virtually straight from the Oracle tutorials

BufferedReader in = new BufferedReader(
  new InputStreamReader(
  new URL("http://www.oracle.com/").openConnection().getInputStream()));
If that code doesn't sent you screaming and running from the building I don't know what will!

For Perl, I typically cheat and open a pipe from the system "wget" command, but using Perl libraries isn't so hard. There's many library options with Perl. The HTTP::Tiny library is particulary simple:

use HTTP::Tiny;
my $http = HTTP::Tiny->new;
 
# get a single page
my $response = $http->get('http://example.com/');
die "Failed!\n" unless $response->{success};
print $response->{content};

But with Ruby, things are even simpler, especially since a standard library provides the simplicity. Here's a line from that Strava API example, in Ruby:

Net::HTTP.get(URI.parse(url))
Now that's a degree of simplicity I can handle! Imagine being asked, without reference materials, to have to write either code, for example for an exam. The Ruby code you should pretty much nail with maybe 30 seconds of study. For the Java, well, good luck.

So I'm not dismissing Java right yet. But it seems if I want to get something working, server-side web via Ruby and Rails is the quickest approach to providing some useful Strava functionality, assuming DeltaWebHosting will allow me access the JSON library, something I need to check.

1 comment:

Admiral Adney said...

I was hunting for rails development company and landed onto your post and i must say thank you for sharing such useful information.