Monday, June 4, 2007

The Beauty of Ruby

The Beauty of Ruby



I've been working more and more with Ruby on Rails. I'm hoping to be able to work full time with it in the next few years, but for now I'll just have to keep sneaking it into some of the bigger things I get paid to do.

Its too bad because Rails and Ruby could really help some of the clients I work for. I really haven't been this excited about a programming language since I learned C back in the Eighties!

One of the main benefits of Ruby on Rails is how opinionated Rails is. Rails does not try to be everything to everyone. It is trying to meet most of the needs of the average web app, but not trying to give into everyone's slightest whim. The coding needed to provide for most of what you need will be simple and straightforward with Rails. If you want more esoteric fluff, you can use J2EE. There are plenty of alternative solutions, but if 8 out of 10 apps you write fit in the middle, why are you forced to carry the luggage and infrastructure to support those few times the exotic stuff is needed.

Working with Rails is like working with a framework that imposes the KISS principle on your apps. It really results in savings and efficiency.

As I've worked more with Rails, I've begun to truly appreciate Ruby. Like many people in the last few years I came to Ruby through Rails. I started using Ruby as just another language. Most of what you know in any given language is available in any other. The biggest differences are between the procedural and the object oriented languages, but you might be surprised and how similar even these are in practice. Take Java for example. It is a fairly object oriented language. Its not pure OO, and it doesn't claim to be. Java's basic types are not objects. You know strings, floats, characters, and such. However Java is a pretty good example of a modern OO language. However you'll notice that quite a bit of Java was written by people who think like procedural programmers. take a walk through Java's network classes and you'll see the same kind of coding I was doing back when I learned C in the 1980's.

I shouldn't complain because I certainly wouldn't have done a better job. Heck, I wouldn't have done nearly as good a job as the people at Sun did.

Objectification


With Ruby everything is an object. You cannot cheat. You have to code in OO style. Better yet Ruby truly embraces its Object Oriented-ness! You often don't call a method on an object, the method invokes its own method on itself. For Java's class Math one of the methods is abs, a function that lets you compute the absolute value of a number. For example for an integer the function looks like:


Java code:


public final class Math {
...
public static int abs(int a);
public static long abs(long a);
public static float abs(float a);
public static double abs(double a);
...
}


You would use this method on an integer like this:


Java code:


public class MathExample{
public static void main(String[] args) {

int i = -7;
System.out.println("i is " + i);
System.out.println("" + i + " is " + Math.abs(i));
}
}


This is pretty standard stuff. It should be easy enough for any programmer to understand. For output you would get something like:

i is -7
|-7| is 7



What's not object oriented about that? Math is a class. abs is a method of class Math. Heck abs is even multiply defined so the same method can be applied to multiple data types! Math.abs() that is object oriented!

Yes it is.

So what's Ruby got?

Let's just look at How Ruby would do it first:


Ruby code:

puts 'i is ' + (-7).to_s
puts 'i is ' (-7.abs).to_s


The heart of that is when negative seven calls its method abs on itself

puts -7.abs


Yep, that's all folks. Remember Ruby is a pure object oriented language, so the integer '-7' is an object. The object '-7' is of type int and has a method called abs. -7 is calling its own method on itself! Lucky number seven.

The puts (for put string) looks like a normal function call with a function name followed by the object to perform the function on, but we could give objects a 'puts' themself method. You can see how we used the numeric object's 'to_s' method on itself to turn it into a string. The object that the puts function was operating on was not enclosed in parentheses as they are optional in ruby.

If you don't believe me, give it a try yourself. If you follow that link you will be on a site that lets you try out Ruby code at an irb prompt, thanks to Why the Lucky Stiff.

How does Ruby do it?


Well, lets look into the class definitions in the Ruby api and look up how abs is implemented in Ruby (remember Ruby is written is C):

/*
* call-seq:
* fix.abs -> aFixnum
*
* Returns the absolute value of fix.
*
* -12345.abs #=> 12345
* 12345.abs #=> 12345
*
*/

static VALUE
fix_abs(fix)
VALUE fix;
{
long i = FIX2LONG(fix);

if (i < 0) i = -i;

return LONG2NUM(i);
}


That's the implementation of the absolute value behavior for fixnums. All of Ruby's numeric types get an appropriate form of this behavior. Every numeric type in Ruby has the ability to calculate its own absolute value. As I use Ruby more and more, I am starting to truly appreciate the joys of object oriented programming.

There is truth in beauty.



2 comments:

gazeteler said...

that is wonderfull..

Offshore Software Development Company said...

I was searching for ruby on rails company and landed up on your post and i must say thanks for sharing such useful information.