11/17/08

Riding the rails - Ruby on Rails Tutorial for begginers (part I - Ruby objects)

This one goes for some friends I had convinced with my Rails enthusiasm and want to give it a try and I owe them some work on it.

The first thing one has to know about Rails is that Ruby is not Rails. Period. Ruby is an interpreted, dynamic language; Rails it's killer application. But that doesn't mean learning Ruby without learning Rails is worthless, nor isn't true the myth that Rails is difficult because of it. It's actually the opposite: Ruby is a very nice language that can do almost everything as well as other languages, and as everything, has its own advantages. Rails was built on Ruby because of the language dynamism itself, it was just a perfect situation. I'll try to show why along these posts.

There exist many resources of the Ruby language, starting for it's own documentation. I'll try to give a brief but complete start guide, assuming you have some programming experience (not a lot, though) I'll also assume you have Ruby installed (which should be pretty easy unless you use exotic computers) and you've got irb up and running. If you plan to learn Ruby, don't be afraid to experiment with irb, it's actually a must.

Ruby in a nutshell (but briefer)

Everything is an object

Welcome to the world of Objects. In programming, the Object Oriented Paradigm (OO) states that a class is the abstraction of which a thing is represented. Think of it as a mold, from which actual things are going to be created. The classic example: the Dog class. Let's try it in irb:
class Dog
end

Voilá! We had defined a new Dog class. Unlike Java and friends, it doesn't need to be defined in its own file, or be included in a namespace (although it's recommended by good practices, I'll taking on that later). But now, what does that do?

Well, now we can create dog instances, which are separate entities that are represented by the Dog class. Let's see
lassie = Dog.new
bingo = Dog.new

We have created now two different dogs, which come from the same class, and assigned them to a variable. A variable is simply a label for an object, it's a way to keep track of objects.

Buh, these dogs are pretty boring, they do nothing! I would not want such a uninteresting dog, so let's teach them some tricks.
class Dog
  def bark
    puts "Waff, waff!"
  end
end

Ok, I'll admit it, barking is not such a great trick, but it's enough for demonstration purposes. In this piece of code, we reopened the Dog class; this means that we can alter classes later on the flow of the program. It was done just by stating the Dog class again. It may seem like the entrance to chaos, but I assure you that is actually a nice feature that some other languages don't have and can be used well enough.

Inside the class we defined a method. Methods are procedures or actions that execute some code when they are called. Let's call it:
lassie.bark

Woah, lassie is barking! That is how you call instance methods in Ruby: with the dot operator (.) When you append a point to an instance of a class, you are trying to call a method or access one of its properties (more on that soon). By calling lassie.bark you are invoking the bark method defined in the Dog class, from which lassie was created.

If you come from other languages, you may notice that we called a method without parenthesis (that is, lassie.bark(). Well, Ruby is full of syntactic sugar, and parenthesis are not always necessary. Eliminating the unneeded ones reduces a lot the code noise, which is important. But, if you really miss them, typing lassie.bark() will work as well. Actually, we did another method call without parenthesis in case you didn't notice. Where? In the puts "Waff, waff!". puts is just another method, and we are passing the parameter "Waff, waff!", which is a string. Strings are just text, and the form to indicate them is to surround them with quotes. More info on Ruby strings here.Parameters are arguments (or "things") that are passed to a method to do something with them, as our dogs will soon be able to demonstrate.

puts method just prints whatever you send to it to the screen, and it doesn't seem to belong to an instance of a class, but in fact it does. It belongs to the toplevel, which is a magic construction I'm not to cover right now. But learn from this: even puts is part of an object. And it can be called with parenthesis also, just try puts("Waff, waff!") and it will do exactly the same thing.

These dogs are very dumb. I remember their names, but they don't. Let's give them an attribute 'name'. Attributes are just variables that belong to instances of a class and are defined on it. We'll reopen again the Dog class, and add the attribute and a new trick.
class Dog
  attr_accessor :name
  def salute
    puts "Hi, I'm " + name + "!"
  end
end

The attr_accessor instruction is the way for a class to indicate an attribute that is readable and writable by external objects. The parameter to the attribute accessor is :name, which is the Ruby syntax for symbols, which are just objects used to represent other objects, in this case the attribute name. Now our dogs can have a name:
lassie.name = "Lassie"
lassie.salute

Woah! Our dog talks!. By declaring an attribute name, Lassie can remember her name, and when we invoke the method salute, she will say it. But if we try to get Bingo to say his name:
bingo.salute

We get an error: TypeError: can't convert nil into String. That is because we hadn't assigned a name to Bingo, so his name is nil. Nil is the representation for nothing. And Ruby doesn't know how to concatenate a string with nothing, hence the error. Exercises for you: give a name to bingo and make it say it to you. Change name to Lassie (after all, it's very old fashioned ;D). Create a new dog, and name it however you want. It should be easy pie.

To finish this part, I'll just point you to one of the most wonderful things in Ruby: introspection. Our dogs not only needed to know what their name was, but what can they do. In general, objects can retrieve information about its own methods, properties and classes by their own. For example, just type:
bingo.methods

and it will present to you a bunch of "tricks" that Bingo can do. That is, all the methods that bingo has. You see a lot of standard methods that all objects have; if you only want to see the methods belonging to the Dog class, there is another way:
Dog.instance_methods(false)

And it will give you the methods defined just in the Dog class. The parameter false is just the indication to the method to exclude all methods defined in superclasses or modules: don't break your head by now, I'll explain it later. If everything went right, you should see your bark, salute methods, as well as name and name= methods, which are the ones added by the attribute accessor. In fact, even attributes are instance methods in disguise. But don't complicate things, and just think of them as "things held by other things".

Now you can have fun in irb creating classes and methods. In the next post I'll be covering: blocks, iterators, exceptions and standard classes. See you later!

2 comments:

Unknown said...

In fact Ruby **is not Rails**, but you can't deny it's great influence for the new-rising popularity of the Ruby language.

Ruby as a language permits to be more dynamic and flexible, the perfect 'glue' tool.

I have the opportunity to see you in your talk about JRuby at UNAM.

seo company in mumbai said...


The blog is quite resourceful, however a touch of the professionals can diversity it even further. Our experts promise a fine quality all assignment The best experts in the business are here to take care of your academic needs.
students can receive online academic support.
Ruby assignment help