Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Tuesday, September 22, 2009

Mid-Twentieth Century Languages

In the News:

Dell to buy Perot. Having trouble competing with HP? Here's an idea: go head-to-head with IBM.

Mid-Twentieth Century Languages

Ruby's powerful and full of Tim Toady. Python's powerful and pythonic. In one area, however, both are bad reminders of the 1960s.

I refer to the fact that both are strictly interpreted, according to the lamest definition of the term. They begin processing at the top of the file. Declarative code? Processed. Imperative statements? Processed.

The intelligent way, of course, is to read the file handling all the declarative code first. Functions, for example, are defined and ready for use when the imperative code is processed. Functions may be declared where they make sense. The structure of the source code is not dictated by the processor; it's decided by the programmer.

Ruby and Python? Nope. Don't place your imperative code at the top of the file; library functions at the bottom. You cannot call a function from statements above the function's definition; you cannot instantiate an object ... This is stupid.

JavaScript eats your source code's declarations first, then goes on to process your imperative code. JavaScript is not the world's most advanced language. That Ruby and Python are less advanced than JavaScript should be an embarassment to both.

If you remember Pascal from the early days of microcomputers you remember being forced to write your main program at the bottom of your file. This was, and is, a tragedy if you valued readability. This is how you must structure your Ruby and Python.

JavaScript gets this right. Java lets you put "main()" where you choose. This should be completely standard in this century.

Friday, September 11, 2009

Error Handling

Today is 9/11/09. John and I played an hour of tennis once a week from 7:30 to 8:30 in the morning. We played eight years ago on this day, quite happily ignorant of the events unfolding in Manhattan. By 9:00 we were a half-hour apart, at our respective offices, watching TV. We haven't played since. And so it goes.

Error Handling Overview

Some processes can generate errors despite the most skillful coding. Disk I/O is one example. (User enters name of a file that doesn't exist. Data cannot be written because the disk is full.) I first met try/catch logic in the mid '90s in Java as a way to handle these sorts of errors. This is now a feature of most mainstream languages.

The basic idea is to surround a block of code (such as disk I/O code) with a "try this" instruction. Following the block to try there is an "if an error occurred" block. Some languages, Java included have an optional "whether or not there was an error do this" block. Code in the "try this" block (including, importantly, subroutines called in that block) can "throw" an error, often an Error or Exception object for use in the "if an error occurred" block.

Error Handling in Java

This is the basic Java syntax:


try {
}
catch (Type1ExceptionOrError var1) {
}
[catch (Type2ExceptionOrError var2) {
}]...
[finally {
}]



Java has both XxxException and XxxError classes. The builtin classes can be extended by the programmers to create more Exceptions and Errors. Multiple catch clauses allow code to be written to handle particular Exception or Error types. Importantly, catch (Exception e ) {} will catch all exceptions, though it loses the ability to use any added information in extending classes. Errors can be handled similarly, but are generally not handled. A Java Error would be something like a hardware failure that the program probably cannot deal with successfully.

If I were redesigning the language I would eliminate the finally block entirely. The catch blocks should simply branch to the code that follows the last catch block.

I would then use only a single catch block. If needed, the programmer can put a switch inside that block which calls code appropriate to the exception type.

That said, let's look at the ways some other languages address the issue.

Error Handling in JavaScript

JavaScript follows Java's try catch finally lead, with two important differences. First, there is only a single catch block. Second, the thing caught may be anything: object, string, number, ...

In JavaScript: The Good Parts, Doug Crockford eliminates the finally block, leaving exactly what I recommend for Java.

Error Handling in Python

Very like Java, but the catch block is known as an except block.

Error Handling in Ruby

Similar to Java, but Ruby stubbornly goes its own way. You don't try, you begin. You don't catch, you rescue. You don't finally, you ensure.

Ruby also features a retry keyword that repeats execution of the try block.

"Martin, don't forget that stupid Tim Toady! You can use catch blocks, too."

"Thanks, Monty. I'll put that in."

Monty, my pet python, knows just enough Ruby to criticize it.

Error Handling in C++

Like Java you have try and catch blocks. Unlike Java there is no finally block. Also unlike Java, there is no restriction on the type of thing caught. Strings and integers, for examples, can be caught. There is also a generic "catch anything" variant, though there is no way to hand the thing caught to the code in this catch block, a disadvantage of strongly-typed languages.

Friday, August 21, 2009

The Bug from Hell

Executive Summary

One full week lost. Zero output units. It was the bug from hell. If you have any faith in your software schedules, read on.

I am writing a SketchUp Ruby. Stuff that worked Friday stopped working Saturday morning. I got to the bottom of the problem Thursday morning. In a lifetime of coding I've never been stopped for five days by one bug. It was subtle.

The trickiest bit about Rubies is that your UI runs in a browser. That means that the Ruby code that manipulates the model has to communicate with the JavaScript in the browser. (Note: this is another case where you have two languages to use and zero choices about which you use.)

JavaScript on the Front Line:

The general idea is that since the user is in charge, JavaScript notes what buttons are clicked or whatever. JS can then call a Ruby function that will dig up whatever data is needed or manipulate the model in the manner requested. If it needs to send data, Ruby prepares a bit of JavaScript, like this:


script = 'name_of_javascript_function( whatever, facts, are, required )'


Ruby hands this script to a webdialog object (prepared by the web dialog and passed to the Ruby callback). The webdialog executes the script, presumably calling JS functions that make use of the data. The whole communication thing is at best inelegant. This is NOT pythonic.

"No, no, Monty! I didn't mean you. You are totally pythonic."

Monty, my pet python, has been crabby since I turned him into a vegetarian. Sorry for the interruption.

Ruby in the Trenches

Saturday morning I moved the JavaScript out of the HTML file and into a separate JavaScript file so I could validate the HTML. I've got validated HTML, but the code no longer worked. It seems that JavaScript correctly calls Ruby. Ruby correctly gathers the data wanted and correctly forms the script needed. But Ruby is definitely not succeeding in getting back to JavaScript. The final step, executing the JavaScript script, is not happening. At one point the JavaScript function that I wanted called by the script was reduced to launching an alert box that said, "Hooray! Finally!". It never said "Hooray! Finally!".

Note that the tool set is completely primitive. There is no NetBeans, no Eclipse, no debugger. On Windows, we can choose any browser we like, provided we choose MSIE. At one point it reported that I had an error in my JavaScript at line 51 million and something. Ugh. The tiniest little bit of error checking and it's too buggy to be helpful.

For debugging, you stick print statements into the Ruby and pop up alert boxes in JavaScript. Before Saturday ended I knew that my JS was correctly calling Ruby, that Ruby was preparing a valid script passing correct data and was calling the correct method of the webdialog (the webdialog that JS had passed to Ruby). And that was the end of the road.

Swapping Code

By Tuesday I knew that the same code that worked also failed. I started with a successful, small test package and the unsuccessful, larger actual package. I began removing parts of the larger package deleting bits one a a time until I could find the guilty party. I ended with a still-failing package no larger than the test package.

Wednesday found me copying Ruby source functions from the test to the failing routine. Still fails. Copy from the failing to the test? Still succeeds. So repeat this with the JavaScript functions. Same result.

Early Thursday I am convinced that it is a timing issue. How else could two copies of the exact same code fail and succeed?

"Martin, what are you talking about? It's single-user, single-threaded code! Timing issue?"

"OK, Monty. You explain it."

That got me back to Saturday morning. I had taken the JavaScript out of the HTML, where it had been at the end of the body of the page, and put it into a JavaScript file. I linked to the JavaScript file from the <head> section of the HTML, a common practice that I will never again practice.

Moving the "load the JavaScript file" command from the <head> of the HTML to the end of the <body> of the HTML turned the failing code to successful code. Bug in the SketchUp linkage: if your HTML is not completely processed, the webdialog that it passes to Ruby cannot execute the JavaScript script.

Moral?

(In Ruby convention, getters for booleans are suffixed with a "?". This section should return a boolean.) Moral? Maybe.

I let my ego get in the way. Hot shot programmers fix their own bugs, right? Instead of punching ahead on my own, I should have recruited an associate. Wise old programmers get help when they need it. I'll try to remember that.

Saturday, August 15, 2009

JSON in Practice

Writing JSON:

I wrote a specific-purpose JSON writer, in Ruby, to encode the data I needed. It wasn't too tough:


# JSON to send to webdialog
def makeJson( layer_names, scene_names, vis )
ret = '{ '
ret += 'layers:' + makeJsonArr( layer_names )
ret += ', scenes:' + makeJsonArr( scene_names )
ret += ', vis:\"' + vis + '\"'
ret += ' }'
return ret
end

# convert array of names to JSON array
def makeJsonArr( names )
ret = '[ '
start = true
names.each do |n|
unless start
ret += ', '
else
start = false
end
ret += '\"' + n + '\"'
end
ret += ' ]'
return ret
end


Reading JSON:

Since JSON is syntactically correct JavaScript, this is the reader that decodes it in JavaScript:


function rubySays( data ) {
eval( 'obj = ' + data );


The rubySays() method then goes on to make use of the object it creates in its first line. I like code that weighs in at just tens of bytes.

Summary:

Writing JSON is easy. Reading JSON in JavaScript is effortless. Highly recommended!

Tuesday, August 4, 2009

Python on Python

Yesterday my python slithered off, mad because I was writing Ruby. I feared he'd swallow the kitten. Since Python lets you create attributes on the fly, I solved the problem:


python.diet = 'vegetarian'


Actually, Python has nothing to do with snakes. The name comes from the British comedy troupe, Monty Python. My python is named Monty. Ruby gets its name from lists, such as wedding anniversaries, where Ruby follows Pearl.

When Python and Ruby engineers debate the merits of their respective languages, the discussion is generally learned and respectful. Monty, on the other hand, can really get going.

"Hey, Monty! Want to talk about Tim Toady?" (He never passes this one!)

"There you are. Tell me what you think of Tim."

"Martin, Tim's a fraud. There's maybe sixteen different ways to loop through an array in Ruby. You got some hotshot coder who never does it the same way twice. OK, boss. Who's going to maintain that crap? Some junior coder who just learned Ruby? I don't think so. You're stuck with hotshot. Hope you like paying his six-figure salary."

"Let's show a little real code." Monty dictates a little Ruby and Python.
Python



ids=[...] # array, listing division's employee ids

for id in ids
    # code processing
    # each id

Ruby


ids=[...] # array, listing division's employee ids

ids.each { |id|
    # code processing
    # each id
}


"You could write that loop other ways in Python, but no one would. That's the one, obvious way to do it. Ruby dudes will write every loop differently to show off their Tim Toadiness. And no, I did not forget curly braces in Python. You indent and you get code that looks like, and is, blocked."

"I could go on, Martin, but I just got this sudden urge for some broccoli. Broccoli? I never ate broccoli. What's going on?"

Monty slithers off. Actually, in Ruby looping by the "each" method is the preferred way, in most instances. The simplicity of the Python illustrates the quality that Pythonistas call "pythonicness."

Monday, August 3, 2009

Ruby, Python and Tim Toady

In the News:

Why Bing Is Gaining on Google

A triumph of creative headline writing. Bing soars from 7.2% to 8.2%. Google: 78%. Yo, Steve. When your competitor's name becomes a verb, they've solved the problem. If you don't want to take my word for it, google it.

Python v. Ruby:

Executive summary: two excellent modern, multi-paradigm languages with fiercely partisan fans who never tire of arguing for their personal choice. In the end, the one you prefer probably depends on where you stand on Tim Toady.

First, the basics. Both languages are interpreted, not compiled. Both are more than fast enough for business computing. Neither is strongly typed. Neither is more error prone than, for example, Java.

Both are object-oriented. Almost everything in Python is an object. Everything in Ruby is an object. (In Ruby, "2+2" is a notational convenience for "2.+(2)". That's an object "2" with a method "+" called with another "2" object as argument.)

Ruby's OO constructs are more Java-like. Python's object model struck me at first as chaos. You start with what in C++ or Java would be two instances of the "dog" class, "fido" and "rover" for example. If fido does tricks, you stick an array field to him: "fido.tricks = ["jump", "roll over", ...]. No need to extend any class, no problem that rover has no tricks.

Multi-paradigm means that unlike Java, you use OO coding when it works for you. You use other techniques and you don't force OO solutions on non-OO problems. For example, both support functional programming: the ability to pass code around and manipulate it as easily as other traditional languages handle strings.

Big difference: Rails. Ruby on Rails is the Ruby language with the Rails website framework. The Rails framework gets all the attention of the Ruby community. By contrast, Pythonistas are split among multiple frameworks, none enjoying the effort put into Rails. Rails JavaScript framework, Pythonistas argue, is based on Scriptaculous which is based on Prototype which has an enduring reputation for bad code.

Both languages work. Spectacular websites can be built successfully with either. Both will give you the same results as you could get with Java EE but with much less code, which will simplify maintenance. Would I recommend one or the other? For me, yes I would. For you? I would not. That's because I have a definite stand on Tim Toady.

Tim originated in Perl (which I recommend you avoid if at all possible). TMTOWTDI: There's More Than One Way To Do It. "Tim Toady" is the way it's pronounced. Ruby, which was designed as a better Perl, features Tim Toady. Pythonistas say, "There should be one, obvious way to do it."

I'd say more on this, but my Python just saw the Ruby code on my screen and slithered away looking very mad. I've got to find him before he swallows the kitten. (Why Ruby? SketchUp plugins can be written in the language of your choice, provided you choose Ruby. How can I explain that to my Python?)