Registered: Feb, 2007
Re: What Are Your Ruby Pain Points, Really?
Posted: Feb 22, 2007 1:36 PM
Overall, I was quite enamored with Ruby when I first started using it. Over time, however, some things started to bother me a bit too much. The purist in my was quite disturbed by, especially, #1 below. Still, I think Ruby is quite beautiful, and it's too bad it has these issues.
1) Inconsistencies in methods on classes standard lib:
For example, I was dismayed to discover that String and Array have very different conventions for what methods are destructive and which are not. This is made worse by the fact that it's "optional" to have destructive/non versions of a method.
For example, String has both "delete" and "delete!", but only one "insert". I guess the developer figured there was no use for a non-destructive "insert", but it's a grey area in my mind and not completely logical (i.e. I can imagine a non-destructive "insert" simply returning a new string with something inserted).
Array, on the other hand, has only "delete", and it's destructive. I assume a different developer with a different way of thinking did this one. Also, Array#delete returns what was deleted, whereas String#delete! returns the string... This makes it hard to remember how these behave - not exactly following the "least surprize" principle.
What makes this worse is that there is really no way to fix the situation. Once you make a destructive method without "!", you cannot go back and make it non-destructive without breaking code. Also, the whole point of "!" is bit nullified because one still has no sure way of knowing whether a method is destructive or not (e.g. String#insert) without looking it up.
For an obvious comparison, it's not always obvious which methods are destructive in Python either, but it has a *great* feature of returning None if it is destructive and returning a value if not. Also, immutable strings help (see below).
Although I see the benefit of "!" and "?" on the end of methods, these conventions are not enforced nor are they always consistently used, and I do think it makes for noisy looking code.
2) Too much "implicitness"
I know that Ruby prides itself in being more implicit than, e.g. Python, and I found things like no need to use "return" explicitly seductive, choosing to use that feature all of the time. However, I also found it can be a bit confusing to read the code and figure out what, exactly, a method is returning (i.e. what constitutes code that causes a return value, etc.). I've grown to like the explicitness of "return" after using Ruby for a while.
3) Mutable strings make for uncertainties
Although mutable strings can be very useful, I can now see the nice thing about immutable ones. In Ruby, you have to be careful to "dup" strings that you do not want modified. If you pass a string into a method, you do not know if it might be changed, etc. There are pros and cons, but in practice, I think immutable strings are more "comforting" when coding.
4) Optional parentheses on methods
I know there are pros to this (i.e. the "uniform access" idea), but I find that deciding whether to use them or not becomes a matter of style, and it can be ambiguous what the right choice is. For example, it might make sense to drop the parens for one-argument calls, but if you need later to use more than one argument, it can be more clear to use parens. I've then felt I was being inconsistent, and I was tempted to go and fix the previous ones, but then I realized this was an arbitrary decision based on trying to be "consistent" within one method or whatever... I find it more "clear" to use parens on methods, I guess. But what about "puts"? Since it *seems" like a statement, it looks better not to use them. I just don't know. :)
I'm sure there are other things I could think of, but these stood out in my mind when writing this.