Mar 23, 2007 @ 11:19 am

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 :

  1. def do_something_clever
  2.   result = first_number + 18
  3. 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 :

  1. result = first_number + 18

means the following to Ruby :

  1. 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 :

  1. class Fixnum
  2.   #some implementation
  3.  
  4.   def +(other)
  5.     #some internal call I am unaware of that does the actual addition
  6.   end
  7. 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
Rate this post :
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 1 out of 5)
Loading ... Loading ...
Posted under : In depth
10 Comments
MyAvatars 0.2

I don’t think this is entirely true.

When you run: “5*8+5″ in IRB, it correctly returns 45. If what you say is true, it would be the equivalent of: 5.*(8.+(5)). The inner method would be called first, returning 13, and the outer method would evaluate to 13*5=65.

So there must be some ruby language magic doing the order of operation rules.

Comment by : jc
— March 23, 2007 @ 1:11 pm

MyAvatars 0.2

jc,

5*8+5 is the same as 5.*(8).+(5) which also correctly gives 45 in IRB.

But I understand what you mean. It’s true that ruby must check for the precedence of operators to correctly evaluate an arithmetic expression. So when you write : 5+8*5 , it gets transformed to 5.+((8).*(5)) instead of 5.+(8).*(5)

Comment by : Frank
— March 23, 2007 @ 1:37 pm

MyAvatars 0.2

There’s a slightly more well-known example for this: the assignment operator. In Ruby, attributes are *always* private; there is *no way* to access them from the outside. (Well, I suppose you can do some meta-programming or eval’ing.) “But wait!”, I here you say, “I *can* do something like ‘foo.bar = 42′, can’t I?”. Yes, you can, but(!) that’s not an assignment (cue Henri Matisse pipe here), it’s a message send. Ruby sneakily transforms

foo.bar = 42

into

foo.bar=(42)

(Note: the equals sign is part of the message name, just like a question mark or exclamation point.)

jwm

Comment by : Jörg W Mittag
— March 26, 2007 @ 9:27 am

MyAvatars 0.2

> …In every single languages that I know the existence,
> every arithmetic, bitwise and conditional operators
> are built-in and global keywords.

You should learn more languages then. Smalltalk, which Ruby copies in many ways, does the same thing, treating *everything* as an object. 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:’, which you might call like ‘methodName Arg1: [ code block for example] Arg2: otherarg’. I don’t know how Ruby implements this, I think there is some magic that goes on inside, like you say.

On a related note, in the “Bring your methods to life with punctuation” post, you say:
> I think ruby is the only language that allows a
> programmer to name his method logged? for example.

Not at all. Common Lisp and Scheme allow quite a few different characters, Haskell allows ‘ in its variable names, and I’m sure there are others, though none of them spring immediately to mind.

Comment by : Joseph Wright
— March 26, 2007 @ 12:05 pm

MyAvatars 0.2

This would be more impressive, if the method declaration would have some way of specifying operator precedence. As it stands, it’s bizarre, it’s consistent because the operators are really methods but they are treated as a special case … well because they have to be.

Is there some type of well documented language spec for Ruby were these things are clearly specified (operator precedence?)

Comment by : Augusto
— March 26, 2007 @ 12:10 pm

MyAvatars 0.2

Jörg,

It’s funny because what you are talking about is exactly the subject of my next article. It’s all written already. I just have to publish it tonight. I hope you’ll enjoy it. I would really appreciate your comments on it.

Augusto, That’s a good question. I really don’t know if there’s some official documentation about that. Anyone knows?

Comment by : Frank
— March 26, 2007 @ 12:34 pm

MyAvatars 0.2

I decided to publish the post about ruby assignments right now, just in case you are interested. (it’s on the home page)

Comment by : Frank
— March 26, 2007 @ 1:15 pm

MyAvatars 0.2

I had actually started cooking up some code examples very similar to yours but figured they would be unreadable in the comments section anyway, without that nice syntax highlighting. Saved me some duplicate work (-;

jwm

Comment by : Jörg W Mittag
— March 26, 2007 @ 5:25 pm

MyAvatars 0.2

Jörg, yeah it would have been nice if the syntax highlighter was active in the comments as well. (it might had been a little heavy on javascript though… =) )

Joseph, thanks for the info about smalltalk having the same possibility. I have updated the original post.

Comment by : Frank
— March 29, 2007 @ 4:37 pm

MyAvatars 0.2

83d724b2c6a6…

83d724b2c6a6ff3fe4d0…

Comment by : 83d724b2c6a6
— May 11, 2008 @ 6:31 am




Leave a comment
Name (required)
Email (will not be publish) (required)
Website