Monday, February 18, 2008

Python vs Ruby: Fight

Python Vs Ruby: Fight

THe other day I had to do a little to modify some existing Ruby scripts, and to see what all the hype was about, so I picked up the Pickaxe book, and learned some Ruby. Now there's been a better post on this topic, by wiser people than I, but here are some of my impressions regardless.

But, these comparisons are coming from "Someone who's been using Python for 8 years now, and Ruby for a week" perspective, so they might be off-base a little.

Introspection:

Ruby plays this game pretty well, with a number of introspection methods baked in to Object. I can get class type, different flavors of members (both functions and data), and other obvious things.

Python's inspect module, however, really rocks. I can get submodules in a module (which I can't seem to in Ruby), I can retrieve the source code for any object (so, anything) - even print out the source for the file that contains whatever object.

Winner: Python and its inspect module.

Representation Of Objects:

A little bit like introspection, but this time we have a more specific focus: members. Ruby's Object level inspect method is a good idea - by default give us ID and instance variables. I think it gets a good debugging thing slightly wrong though by letting users override this default behavior (via to_s). It would be so useful to have a method that gives us a programmer representation of the object.

Python tries to get it right, by providing both __str__ and __repr__, for "to string format" and "for programmer's eyes", respectively. Python doesn't go far enough to provide a useful default to __repr__ - it should print object ID and instance data. Python makes it overly hard to extract that data - a really good inspect type function, that catches all the edge cases, is hard to write. (Although I believe I have one in inspect_).

Winner: Ruby when objects do not provide to_s methods

Syntax:

Python's 'whitespace is syntactically significant' approach turns off a lot of people. Ruby gets around this issue with its end statement: meaning it doesn't care about whitespace, but it also doesn't require a "begin" statement all the time like (say) Pascal does. However Ruby has this, what I consider to be, an inconsistency: sometimes you don't need a begin, sometimes you need one, and sometimes you need a do statement instead. While requiring a begin statement all the time might make Ruby feel like Pascal, and less like "an intelligent language where you only need the end statement", it's annoying to the n00b (me) to question, "Now how do I start this chunk of code?"

Python has its own series of warts. It's hard to debug something you can't see, and you have to be careful posting and copying Python code from the Internet.

Winner: It's a draw