I’m trying to teach myself Ruby so I figured that I will teach you about it as I go along. This will help me to review what I already know. They say the best way to understand a topic is to try to explain it to someone else :) So I will make this into a cyclical recurring thing. I will start with plain old ruby, but I hope to get to rails sometime soon.
First thing that you notice about Ruby is that everything is an object. And when I say everything I mean it. Ruby has no primitives or C style low level arrays. Everything is implemented as an object. This of course does not mean that you can’t do simple operations on numeric values. In fact ruby makes things much less verbose than many other languages. For example consider the following:
temp = -2.abs
The lack of primitives means that you can call methods on anything. The value of temp will be the absolute value of -2 which is 2. Every single part of the language is implemented this way. The following two statements are equivalent:
temp = 2+2
temp = 2.+(2)
All basic mathematical operators are implemented as methods. So when you add two numbers, you are really calling a method with an argument. This works for absolutely all operators – even the array square brackets:
temp = somearray[1]
temp = somearray.[](1)
How awesome is that? This opens up a whole new range of possible ways to implement certain things. For example in Ruby the simplest iterative loop will look like this:
5.times {|i| puts i }
Note the pipe operator in there. This is Ruby’s syntax for specifying a block argument. At each step of iteration the times method returns a value which then gets assigned to i. The puts is a kernel method equivalent to java’s System.out.println.
You see, puts is simply an alias for Kernel.puts. Kernel is simply a top level, core class that contains all of the most useful Ruby utilities. If you look in the documentation, the kernel method puts is in fact an alias for:
$stdout.puts
What is $stdout? It is a global variable. Most Ruby variables have a local scope contained to the current code block or method. You can indicate scope using one of the following prefixes:
- $ – global variable accessible to everyone everywhere
- @ – instance variables used within a class
- @@ – class variables are equivalent to java’s static variables
In addition, all variables starting with an upper case letter are considered static. Before I go any further I should probably note that all of Ruby’s variables are duck typed. What does that mean? It means that the type is not declared but evaluated at runtime (if it quacks like a duck…).
So how do you initialize a class? It’s easy:
class Foo
def initialize(bar)
@bar = bar
end
def foobar
puts @bar
end
end
You can probably figure out why do we need the @ sign on the instance variables. Ruby does not require you to create initialization block of variables in the class body like many other languages. It also does not require you to initialize all your instance variables in the constructor. Ruby instance variables can be initialized in virtually any method within a class. Thus the only way to distinguish instance variables from locals is via that @ thing.
You also probably figured out that initialize is a generic name for the constructor in each ruby class. If you didn’t then I’m telling you about it right now.
That’s it for today… Obviously, I haven’t covered all the basics yet. I still have to mention Ruby’s implementation of hashes, boolean operations, inheritance and etc… But that’s something I will be tackling next time, in Learning Ruby (Part 2).
In the meantime you can always browse through the Ruby Documentation.