Ruby Tuesday
Sterling Camden
Based on a recommendation from apotheon, I started learning Ruby yesterday. I must say I am impressed. Up until then, I had been a big fan of C#. And yes, I realize that C# plans to implement some Rubyesque features like lambdas in version 3.0, but even then it looks like Ruby’s implementation is much more agile.
As a long-time type-safe OO programmer, some of the features of Ruby made me shudder at first. No type safety, automatic variable declaration, the ability to modify or extend imported classes… Heresy! But the more I look at it in usage, the more agile and powerful these features seem to be.
Type safety is one that I’m still a little worried about. Type-safe compilers have caught more of my errors than I care to admit. But I can see that it isn’t as important in Ruby as in some languages. For one thing, the interpreter quickly catches missing methods. It isn’t like incorrectly casting an object pointer in C++ where you blow up with some totally unrecognizable exception. And the fact that you aren’t forced into the traditional inheritance model of OOP means that you can construct some powerful variations of inheritance (via mix-ins especially) that C++ (multiple inheritance) and C#/Java (interfaces) can’t even begin to think about. It means, for instance, that two totally unrelated classes can inherit the exact same code without having any common ancestry. And they can operate that same code to differing effects, if needed, via code blocks or by overloading other methods.
Code blocks are the sine qua non of Ruby. Without that, much of the language would be impotent. But with it, Ruby becomes exceedingly powerful and terse.
In general, it seems to me that Ruby’s philosophy is to put the maximum power into the programmer’s hands and let him/her manage her/his own design principles. In many ways it reminds me of my first taste of UNIX and C back in 1984. You can do anything easily, so you’d better know what you’re doing. Unlike C, though, at least Ruby’s interpreter protects you from crashing the system or worse.
I really like the purity of the object system, i.e., that everything including literals is an object. At this point, I think I’ll steer clear of monkeying around with pre-existing classes at runtime. Perhaps at some point in the future I’ll figure out how that could be useful.
Posted in Coding...OK? |
6 Comments » RSS 2.0 | Sphere it!




two quick points
I’d call Ruby "concise" rather than "terse", probably. Maybe that’s just me.
While I haven’t really looked into it, apparently Rails wouldn’t be able to do all the nifty things it does without the ability to "monkey around with pre-existing classes at runtime", to borrow a phrase.
Glad ya like it.
Maybe "concise" is better. "Terse" may carry the connotation of "brief to the detriment of informing the listener". Another term that comes to mind is "laconic" — named after Laconia in Greece. The Laconians (Spartans) were famous for saying much in only a few words. That fits Ruby, I think.
The idea of code blocks go back to Smalltalk 74 (at least to my knowledge).
I don’t know if modern Smalltalk supports REAL types like you see in C++/C#/…. Back then, the only concept of
that existed was whether a message was implemented on a class.
I never learned SmallTalk, but from what I’ve read Ruby counts it as one of its ancestors. The same concept of type applies to Ruby, also. There are no primitive types — every type is a class. And in Ruby, you can extend any class by implementing a message handler (method) for it.
Thanks for reading and commenting, David.
Lack of variable declartion at the local level doesn’t bother me so much, as local variables still have to be initialized before they can be referenced. But for non-local variables … my day-to-day language is Java and I can honestly say it’s been a long time since I introduced a bug because of a typo with a variable name. I can see why Ruby does it, but I wonder if they should have made it harder to introduce instance variables on-the-fly. In most usages would you really want to have instance variables automatically come into existence when they are assigned/referenced? I’m just so used to letting the compiler catch most typographical errors…
Good point, tuyen — I was also uncomfortable with this feature initially (and sometimes I still am), having fallen in the trap many times in both Fortran and Visual Basic. OTOH, I believe it fits with Ruby’s philosophy of empowering the programmer but expecting her/him to be responsible for checking his/her own work. I can’t tell you how many hours I have spent just getting casts correct in C++ to eliminate compiler warnings, which really had no effect on the code itself. Yes, the same compiler warnings have also caught some real bugs.
I haven’t checked out CheckR yet (a lint for Ruby), but perhaps that would be a nice compromise. I.e., validate the code when you want to instead of on every compile. I don’t know if it catches similar variable names or cross-overs between global, instance, and local variable names, though. I’ll have to give it a look and see.
Thanks for reading and commenting.