October 28, 2003

Flaws in Ruby

I am in general very fond of Ruby. It's a very appealing language allowing all kinds of object-oriented designs not available in Java and other traditional languages. However, there is no such a thing as a perfect language, and there are a few details in Ruby that bother me. For example:

  • The Perl heritage. Ruby uses variables named $`, $', etc... This hacker parlor trick is the worst outrage you can inflict to a program. You are guaranteed to confuse anyone who isn't intimately familiar with Perl if you use these variables. Luckily, a module called "english.rb" allows you to use more meaningful names, but not everyone uses it.
  • The end keyword. I am a big fan of meaningful indenting, such as in Python. It bothers me when I read a source and suddenly, I see five "end" words next to each other in decreasing indentation. This is visually unpleasant and clutters the code. And if visually indenting is not an option, at least "}" is not as verbose as "end", which I just can't help spelling in my mind when I read it, even though it doesn't add much to the semantics of the code.
  • No overloading. That's right. If you want overloaded methods, you need to declare one method with a varargs signature and decide what code to invoke based on the types of the objects that were passed. This omission boggles my mind, but it's perfectly in line with Matz' philosophy, who is a strong opponent of orthogonal features because they tend to "explode into complexity".

Matz does have a point with the exploding complexity of orthogonal features. I believe this fact is one of the main reasons why C++ became so unbelievably complex, both in syntax and in semantics. For examples, templates were initially introduced using the "<" and ">" characters. It didn't take long before somebody realized that this new notation would conflict with the stream operator ">>", thereby forcing you to close nested templates with "> >" instead of ">>".

However, I believe that in the particular case of overloading, Matz is mistaken. This is one of the few features whose combination with other features is pretty well understood and still easy to read. The only problem I can think of is when you try to mix overloaded methods with default arguments. The ambiguity of this particular case led to the rule that default arguments can only be specified at the end of the signature (okay, there is another reason for this constraint that has to do with the way parameters are pushed to the stack, but I won't go there).

Matz himself is the first to say that "there is no perfect language". Or rather, his perfect language is not my perfect language. Fair enough.

Ruby is still a joy to program.

Posted by cedric at October 28, 2003 06:44 AM


If you really need the method overloading you can try this package http://mephle.org/StrongTyping/. Ruby is very expressive language where you can emulate a lot of things. Regarding orthogonality you are absolutelly correct, that why it is so pleasure to program in ruby.

Posted by: ruby fan at October 28, 2003 07:19 AM

Cedric, you might like Groovy then (shameless plug)...


Groovy is a python/ruby style language designed for the JVM. So it compiles down to normal Java bytecode & Java classes, yet has much of the power of Ruby (closures, lists/maps syntax, generators, dynamic typing etc).

The nice thing is that both inside the Groovy language and outsite (in the JVM) there is no difference between Groovy or normal Java objects - i.e. groovy objects can use Java objects and vice versa.

Incidentally Groovy fixes all of your 3 complaints.

* no Perlyness
* uses {} for blocks
* method overloading (and operator overloading)

Posted by: James Strachan at October 28, 2003 10:15 PM

The 'end' syntax was the one thing which looked so ugly and BASIC to me that it kept me off Ruby.

Posted by: Sumit at October 30, 2003 09:38 AM

I think Ruby can use { } instead of END

Posted by: Stephan Schmidt at November 13, 2003 06:14 AM

"The 'end' syntax was the one thing which looked so ugly and BASIC to me that it kept me off Ruby."

I had the same initial reaction, but I kept hearing good things about it, so I bought the PickAxe book and dug in. I was soon won over, so much so I that I now manage http://www.rubyxml.com and http://www.ruby-doc.org.

I tend to use { ... }, and only use begin/end for blocks and exceptions, so the sematic difference is more clear. And I rarely need to use any of the Perlisms.

Posted by: James Britt at December 5, 2003 08:32 AM

"The Perl heritage" was my mistake. Their use will be removed or at
least warned in the future, parhaps with exceptions of regular expression
submatches, e.g. $1, $2, etc.

"The meaningful indenting" is plain wrong for a language like Ruby,
where expressions and statements are interchangeable. See the lambda
problem in Python. Guido decided to remove it in the future. But I
won't give up lambda nor value giving blocks. Using the word "end" is rather a matter of taste.

Finally, I am not against "method overloading", but it very easily leads to optional static typing in the language, which changes the language
very drastically, since you need to specify "type" to overload
arguments. Without well-thought design, it can "destroy" the language
and its culture. I have not yet got that well-thought design of
method overloading.

Posted by: matz at May 29, 2005 05:50 PM

As a newcomer to ruby, with a perl/c/java background, I am astonoshed that simple 'argument count' overloading does not work. Surely most people would expect this to work:
class Test
def initialize
def initialize(v1)

Posted by: Allan Kelly at March 14, 2006 03:19 PM

IMHO multiple dispatch is better than method overloading. A method is implemented multiple times like in overloading. At the time of the method call the types of the arguments determine which method is invoked. Something like a big switch generated by the language and containing forward calls to the different methods. But I cannot see how it could be implemented in Java nor in Ruby. They only offer single dispatch on the invocant (the object before the dot of the method call).

Posted by: Nalpdii at March 20, 2006 12:28 PM

i also dislike the use of 'end' (just about the only think i *don't* like in ruby). so, since everybody is saying that this is a matter of taste, does that mean that this will work:

class Hello
attr_reader :msg
def initialize
@msg = "Hello, World"
h = Hello.new
puts h.msg
print "Press RETURN"

Or what about this:

def fib(n)
if (n<2)
print(fib(20), "\n");

in other words, i'm more comfortable with {} coming from C,C++, & C# so what are the precise syntax rules for substituting {} for 'end'? is there anything wrong with how i structured my code above? I keep getting syntax errors & "odd number list for Hash" errors, & i'm pretty sure it has something to do with my syntax, since both of these work in their original form (using 'end').


Posted by: carlo at April 28, 2006 11:20 AM

I personally love the "end" syntax for blocks. Often I find myself liking the usage of plain words instead of so many symbols while programming in Ruby. I think the {}'s show Java and C's formality while "end" expresses Ruby's easy, comfortable appeal.

Posted by: Glenn at December 21, 2006 05:00 AM

When I moved from C++ to pascal I sooned learned to appreciate 'end' since it was in keeping with pascal's neatness. And wow did that neatness make a big difference in productivity.

Well, ruby seems to have that virtue also, and it just seems right. I still avoid curly braces (except for one liners) in my ruby code, but I like the tip above about using 'end' for exceptions; but I'll do it the other way around.

Posted by: GregL at February 12, 2007 03:42 PM

My only problem with 'end' is readability. Tabbing is not enough to be clear on where blocks begin and end. Brackets can be lined up for easy readability.

But, I love ruby, so I use end.

I also would like to see argument count overloading. That's not so ambiguous, is it?

Posted by: Andrew Otto at August 28, 2007 11:46 AM
Post a comment

Remember personal info?