Oh Ruby, who are you trying to fool?

by Frank

In every single languages that I know the existence, every arithmetic, bitwise and conditional operators are built-in and global keywords. Well, once again, Ruby had to do things differently. You might be surprised to learn that most ruby operators are not built-in keywords. Fine you’ll tell me… but what are they then?

Instance methods

What? Yes. I’m afraid to tell you that Ruby is trying to fool you badly. The least we could say is that Ruby is a language who took the OO principles very seriously… in some kind of obsessive way (but we like it for this). Let’s look at it concretly :

def do_something_clever
  result = first_number + 18
end

Beware! Ruby is trying to make you believe that “+” is independent from “first_number” and “18″. Meeeeeeeep! (I just tried to reproduce the irratating sound that you hear on a quiz show when some guy gives a wrong answer. Although I admit it sounded more like the road runner on crack) The “+” sign is not a “sign” at all. It is an instance method of our object called “first_number”, which is a Fixnum. And what is 18? 18 is the parameter for the “+” method, of course!

We almost succeed to unmask ruby’s diabolical plans to fool our poor mind, so hold on. If “+” is an instance method of the Fixnum class, then where the hell is the dot between that so called method and our object? Well, that’s where the fooling occurs. For the sake of readability, Ruby lets you write an arithmetic expression the way you’re used to. Then, it does some magic behind the scene. It adds a dot, trims the spaces and somehow manage to transform the arithmetic expression in a standard object method call.

*** Update : Like JC pointed out, it also takes care of operator precedence. So when you write 5+8*5 in IRB (ruby interpreter accessible by command line), it correctly gets tranformed to 5.+((8).*(5)). Note that I don’t know exactly what kind of magic ruby does. I just know for sure that “magic happens somehow” ***

So :

result = first_number + 18

means the following to Ruby :

result = first_number.+(18)

If you really wanted to, you could very well write all your arithmetic expressions the way it is illustrated in the 2nd example, but then people would start hating you and soon you wouldn’t have any friend left. Is this what you want? I don’t think so. Still, I think it’s important to know what’s really happening behind the scene when you write an arithmetic expression.

The same holds true if you use numbers directly in your expression, that is, without storing them in some named objects. In fact, in these cases the name of the object is the number itself. This means that once again, you could have done : result = 5.+(3) and thus taking the unnecessary risk to lose all your friends while living a life of misfortune and pain. Again, that’s not what you want, so I suggest you stick with result = 5 + 3. This last paragraph has been edited on 03/31/2007, thanks to Gary Wright.

Finally, here is how the “+” method declaration looks like :

class Fixnum
  #some implementation

  def +(other)
    #some internal call I am unaware of that does the actual addition
  end
end

As simple as that. All of this gives some strength to the statement : “In ruby, everything is an object”, don’t you think?

#UPDATE 03/29/2007
Thanks to Joseph Wright who brought to my attention that the same thing was possible in smalltalk. I wasn’t aware.

[talking about smalltalk...]
When you define a method, it can either be infix (also called binary), which allows for e.g. ‘5 + 5′, where ‘+’ is the method; unary, which has just one argument, or keyword, which looks like ‘methodName Arg1: Arg2:’
[end quote]

Bookmark this post : These icons link to social bookmarking sites where readers can share and discover new web pages.
  • DZone
  • Reddit
  • del.icio.us
  • Digg
  • Furl
  • Technorati
  • StumbleUpon