My first impressions of Ruby
Courtesy of Professor Horst von Brand (a very bright, soft-spoken man), for whom I'm assisting the Operating Systems and Programming Languages classes at Universidad Santa MarÃa, campus Guayaquil, I just finished reading Why's (poignant) guide to Ruby, and I think it's time I shared some of my impressions with you guys. Let's start with my observations on the book, and strictly on the book:
- The book is funny. You gotta admit the author has a soft spot for weird jokes, and hand-drawn foxes.
- It's also heavy on words, and light on explanations. Many things I had to figure out of context, instead of having the book explain them directly to me.
- I found myself skimming very quickly over the jokes and sidebar inserts to get to the code in order to actually learn Ruby. Maybe I'm just the kinda guy that likes to get things in his brain as fast as possible, without intermediary jokes. But I cannot honestly say that the jokes were bad. Weird, but not bad.
Now, on the language. Bear in mind that I come from the Python world, and by this, I really mean that I found myself mentally rewriting the code snippets in Python:
- First, the basics. Ruby is a strongly and dynamically typed, interpreted/intermediately compiled, fail-fast, introspection supercharged, very organized language. This, in short, means that variables' values never change its type, although you can freely change what the variables refer to, and hence the type of the referent. This also means that the code is compiled for the Ruby VM and then executed. This also means that the language has very powerful introspection facilities, a great thing to have when everything inherits from a single Object class. This also means that any error makes the interpreter fail, fast, and failures are verbose, via exceptions. Of course, these things are all true for Python.
- Ruby seems to be very powerful. Modern language features like garbage collection, closures, pass-by-reference and several other niceties are a must today. And Ruby seems to do a more-than-decent job at integrating them. Basically, I think Ruby really leads to compact, nimble code. But so does Python.
- Closures. Closures are pervasive in Ruby. Great thing, which even goes further into the future than Python (although inline functions and lambdas do help a great deal to alleviate the lack of closures in Python-land - I use them all the time).
- For lack of a better word (I'm a bit drunk), I'll use the term "protectedness". There are facilities included in the language to formally declare private instance variables as public (called attributes). Basically, instance variable values are closed to access by default, and you need to specify the public interface for your class using the provided facilities. That's either good, or bad, and the veredict is exclusively on your hands. Proponents of strong type enforcement and strong encapsulation like this, because (they say) it leads to reduced possibilities for program breakage, and, as the ulterior result, fewer bugs. Personally, I'm against these ideas. I should be able to change whatever I damn well please from any byte of my program residing in core memory (as long as I can use formally expressed ways to do it). That's why I like Python. The interface is open to access by default.
- Ruby's syntax strikes me as very confusing. Sure, the provisions in place to avoid common mistakes (such as underscores to beautify big numbers, and symbols in the form of
:something
) go a long way to enable bug-free code. But the syntax... oh, my. Braces, bangs and question marks galore! That's a problem for people using non-US keyboards. I had almost forgotten about having to press AltGr, and here comes Ruby and spoils that bliss. Alright, I'll be fair and say that C is a much worse offender than Ruby. But, syntax-wise, writing Ruby feels like Yodaspeak: you end up writing some sentences practically in reverse of what you thought inside your head. Python feels more natural to me, a Spanish and English speaker. - The
end
delimiters of functions and classes: I'm not a big fan of them. I've become very, very used to the notion of dedents finishing code blocks, so I honestly do not think the famousend
have a place in modern languages. Plus, it reminds me (and I really don't know why) to BASIC. Contrary to Professor von Brand, I do not think using indenting as a beauty feature qualifies as valid. Modern computer languages should accept that doing so, and entertaining delimiters as well, is a redundancy that belongs in Hell. If I'm indenting the code already (which I guess you're doing too, especially when assisted by KWrite or something like it), why should I also be placing delimiters? - The notion of redefining a class at runtime, without the need of defining a new, inherited class, empowers the developer greatly. This is very much like the
Class.prototype
feature of JavaScript. Together with Object, It means that you can supercharge Ruby's deepest innards into doing anything you've ever wished. Of course, this is also possible with Python, although it's a bit more awkward there (classmethod
anyone?). I hear Python's metaclasses and those things you put before functions with an @ sign at the beginning will go a long way to solve this problem in the future. Then again, I may have heard it all wrong. - The language library is foreign to me, and it does not seem as comprehensive as Python's. In contrast to Ruby, the Python library is huge, it's been implemented for tons of architectures, and, so far, has been able to handle all problem domains I've thrown to it. I guess this owes to the fact that Python is a bit older than Ruby.
- I do not understand what all these list and hash methods do in Ruby. Maybe it's because I haven't studied the class library. Sure, a book I can read by pulling an all-nighter... but the last time I read the entire Python library reference, it took me two straight days. I'm not sure I'd like to do that for Ruby, and still muster strength for the
end
delimiters. Especially now that Guido van Rossum and his posse are busy copying all good things Ruby into Python. - The language is damn clean. There are no hacks under the hood, or at least Why's guide fails to expose them. In contrast to this cleanliness, Python has a lot of warts - things that have grown out of control, and petty distinctions derived from the implementation that should not have been there, had some implementation details been thought out more carefully when the creators of the language did not have backward compatibility concerns to consider. But, oh well, I've been looking away from the warts for a long time now. To be honest, you can spend your entire life programming in Python, and not have to look at the warts at all, because all the facilities you're supposed to be using are, indeed, exposed in a formal way. The problem with that formal way, is that it looks a bit hackish...
module.all
,class.dict
and all manner of magical methods.
All in all, if learning Python was a big mental jump from the likes of there's more than one way to do it
Perl, look ma, no Perl CGI
PHP, watch for the SIGSEGVs
C++ and verbosey and compiley
Java or VB.NET, learning Ruby seems to be a similar mind jump. Fortunately for us Python fanboys, it's not a forward leap like Python was, but more like a sideways stroll. It's (nearly) Python dressed in a different sheep's clothing.