Sunday, February 26, 2012

Slow going on coding project

I've embraced Ruby for my coding project. Ruby has been great: I really like it's object-oriented nature: it's inherently object-oriented, with that built in to the core of the language, rather than some sort of kludge built onto what is essentially a sequential language. Actually, I'm not sure whether "object" versus "sequential" is correct, here, since Ruby is still highly sequential, it just heavily uses objects. You can still write Ruby code which looks much like Perl code, with notable exceptions.

But I don't want to write Ruby code which looks Perlish. I want it to look Rubyish. So therein is what makes for slow going: I write stuff, check it, re-read the on-line documentation to make sure I'm not reinventing any wheels (there are a lot of standard methods in Ruby), make adjustments, run, and track down the inevitable bugs. Slow going, but it's what it takes to build aptitude in a language.

So my end-of-Feb deadline for this is not looking good... A few quick examples of issues with Ruby which caused me non-trivial hiccups:

  1. $LOAD_PATH: the default load path, stored in a global array called $LOAD_PATH, or $: for short, changed from Ruby 1.8 to 1.9. Ruby 1.8 loads by default in Ubuntu 2011.10 (which I have), and also in the Mac OS/X in my new, regrettably neglected Mac Air, but 1.9 includes substantial new features. The one which comes first to mind is a Complex variable class. I don't plan to use complex variables in this project, but it's cool that it's there. I prefer to use the latest version. Anyway, I eventually figured out that the local directory (".") is missing from the load path in 1.9, while it is there in 1.8. However, relying on the local directory isn't a good idea, anyway, since you may execute a script from another directory, in which case you want the script's directory rather than the local directory to be in the load path. This is fixed with the following code at the top of the Ruby script: $:.unshift File.dirname(__FILE__). Okay, that's a bit obscure, but it's essentially idiomatic.
  2. type conversion: In Perl, strings are converted to floating point numbers as needed. And all math is done using floating-point (real) numbers, not integers. In Ruby, there is no implicit string-to-number conversion. For example, the "*" operator, which is a multiplier for numbers ("Numeric" class), generates repeated copies of strings. Additionally in Ruby floating point math is not assumed. So if you type puts 1/2 you get zero, because it does integer division which produces an integer result, while if you type puts 1.0/2 you get 0.5, since the "1.0" in the numerator is assumed to be floating point, and it "coerces" the denominator to be also floating point to produce a floating point result. This sort of issue can be particular insideous because you say tau = 0.5 and things work great, then you later change to tau = 1 (perhaps via a command line option), then somewhere in the code you divide an integer by tau and things go south. The key is to convert numbers of uncertain format (and therefore type) to floats with the to_f method, or if you anticipate using complex numbers, convert them to complex. So while Ruby lacks the strong typing of C or Java, it still has distinct number types, and you've got to watch for integer division if that's not what you want. By the way, I've had the same issue with Tcl at work, and it's even worse in Tcl because that language does do string-to-number conversions implicitly, and whether that number is integer or float is determined by the format, so you get a lot of [expr 0.0 + $var] stuff in Tcl to force floating point.
  3. variable names determine scope: In most languages you can name a variable pretty much anything you want (in FORTRAN, the first letter determines number type, but I've not done FORTRAN in many, many years). However, in Ruby you need to be careful. "$" as the first character means global, a capital as the first letter means a class, a lower case as the first letter means a variable, and a "@" as the first character means a class variable. This description may not be precise, but you get the idea... So for example, if I have a parameter describing the "CdA" product for modeling wind resistance, I can't call it CdA because that gets interpreted as a class name, not a variable name. So I am forced to use "cda" instead.

Okay, enough of that. So to mix things up, I then wanted to figure out how I was going to integrate this stuff with the Web. Two obvious options are server side or client side. I think server side is the way to go here because client side would basically mean embedded JavaScript and that wouldn't work so well on mobile platforms. For server side there's many options. DeltaWebHosting, on which I have two accounts, supports PHP and Perl CGI's. I'm trying to liberate myself from PERL, after all, and PHP is perhaps better for relatively simpler tasks than I had in mind. I want to use Ruby. Remarkably, DeltaWebHosting doesn't provide Ruby...

But I found that, a free hosting service, does support Ruby PHP scripts. So I set up an account there and will see if I can get stuff working there. If I successfully convince DeltaWebHosting to install Ruby than I can always move things to my domain there.

Anyway, a lot happening, but progress is slower than I'd like. This balancing the heavy day job + long commute + cycling + running + updating this blog + doing a moderately challenging web project thing isn't as easy as I'd like. Fortunately my cycling is going well this year, my running is hanging in there (once per week), and I am learning a lot in this project, so I can't complain.

No comments: