1. initialize



To create a new object in Ruby you invoke the new class method like so: c = Car.new("Toyota") Naturally you think the constructor would be defined in a method called new , right? Or just maybe a method called Car like in Java? But no, instead it has to be called initialize.

2. Weak typing

even better

4. Global variables



Didn’t somebody tell me Ruby was an object-oriented language?



5. puts



Do we have to copy C’s most ungrammatical, pointless method names?

6. Zero-based arrays



C arrays began at zero to match memory addressing. In a weakly typed scripting language, there’s exactly no reason to do this. There hasn’t been for decades. Can’t we please start the arrays at 1 where God intended? Hasn’t anyone read Numerical Recipes? Aren’t we tired of fencepost errors yet?

7. elsif



Sorry. “elsif” is not a word in the English language, and it shouldn’t have been one in Ruby. Would typing one extra letter have been so onerous?

e

8. $_



Global variables suck. Did I say that already? Global variables you didn’t actually create and that pop up out of nowhere suck even worse. And global variables whose names are indistinguishable from line noise suck still more. Java’s verbose, but that verbosity is in the service of legibility. Ruby’s compactness all too often serves only to obfuscate.

9. Methods are public by default

10. No package access or friend functions.



There’s no access in-between public and private. All too often different classes in the same library/application/codebase need more detailed access to their other parts than the general public should have. Ruby provides no way to manage this.

Just about every developer at some point has used a library or a component developed by someone else. Just about every developer at some point has also gotten frustrated with the library to the point of being willing to find the guy who decided to make a method private and talk some sense into him. Well, most of us wouldn't go that far, but it would certainly be nice to be able to change things that make our lives miserable. It's not that libraries are written by mean people; it's just that even the brightest designers are unable to foresee all the possible ways that other developers would want to use their code.



-- Hacking Java Libraries

Conclusion

Right on. That's annoying.Ahhh... I have promised not to write the same essay more than four times in any twelve-month period. Let's agree that Ruby would beif there was some sort of type inference system that doesn't require type declarations everywhere. Matz was clearly in Raymond Chen mode when he put all the perlisms in the language. As an application developer, I don't use any of them. But I'll accept it on faith that there are people using Ruby as a scripting language who like them.But I don't have to like them.See above. But with extra pursing of the lips. Zero-based arrays are a perfect example of a leaky abstraction . Back in the days when programmers all wore beards and C was the new kid on the programming block, zero-based arrays were really just a funny kind of macro for performing a multiply and add on an integer that you hope is a pointer.No really, it's true. Go ahead, look it up . I'll wait.Okay, I agree with Rusty and then some. I'm perfectly okay with a new language using 1-based indexing. I think I can get over the momentary unfamiliarity as I untrain my brain to stop doing this unnatural zero-based thing.Getting this wrong is almost a rite of passage when learning Ruby. Annoying. But not fatal, fortunately. At least Ruby doesn't assume elsif is a new variable declaration. I hope.See above, again. I really suspect that the Perl-style stuff is of value when writing one-liners on the command line. It probably doesn't belong in an application longer than a page.I would normally say "so don't use them," but there is a small problem with globals: at least one, $=, affects the default behaviour of a kernal function: regular expression matching. For that reason, I consider it a little dangerous.I can live with built-in global variables that are, essentially, syntatic sugar for functions. But I'd rather that they not be syntatic sugar for method calls that change global state. No doubt you cannot have one without the other and thus I dislike them as well.Now about the lack of object orientation. It looks like other langauges have exactly the same problem. What's with all the singletons out there? And what happens when you call java.lang.System.setProperty(...)?It seems that programmers like this stuff, no matter how bad it is for them. Which reminds me, ribs for lunch today I personally don't care one way or the other about what the default access is, but I think Rusty has been perfectly cogent when presenting his argument in favour of restricting APIs as much as possible . And he goes further to suggest that restriction should be the default.Shrug. After all, you can choose what you want. Is there something drastically wrong with assuming that if a programmer writes a method with the default (public) visibility, that the programmer knows what she is doing and wants it that way?Uh, oh. I think I've also written this essay before. Let's move on.But I'll put this one down as a tie. I think Ruby would be a perfectly fine language if you had to take more care to make methods public.By the way, is there a resonance between this perspective and with the way you can declare that certain Rails controller actions must be invoked with PUTs or via XmlHttpRequest?(Something I find quite interesting: most of the Java programmers I have met do not use Java's 'default' visibility. But back to the subject at hand.)There are a lot of security measures you have to put in place if your objective is to hobble programmers. Even then you may find they are motivated to work around the constraints you are attempting to impose:In addition to providing various access constraints, you also have to put together security mechanisms like enforcing sealed packages. Within the Java world, researchers are also proposing sealed classes and even sealed methods.Now I'm not going to say that just because someone can hack around your mechanisms that the mechanisms are bad. I'm perfectly okay with a language that gives you nothing better than a glorified annotation, the equivalent of a post-it note on your ham sandwich saying "mine! don't touch!!"It's useful to document your intentions, even if perfect enforcement is elusive. That being said, I'd like to close with the wise words of another: Less is More . For some people, fine-grained access control is important. But adding that feature is not free.Given the current culture of Ruby programming, I'd say that additional access control would be expensive if you go down the rabbit hole of trying to stop people using Ruby's meta-programming strengths to hack around your restrictions.However, lightweight mechanisms for access control and managing name spaces could be useful.As I suspected before I wrote this, I agree with more than half of Rusty's observations. Isn't this always the way? Most people have far more in common with each other than not.One of the reasons I read Rusty's work so carefully is that he has a markedly different viewpoint than my own. It's nice to read all the nice affirmation from people who seem to value the same things I value, but there is always an opportunity to learn something profound when looking at the same things from a different perspective.

Labels: ruby