This article is meant to be an introduction to the ruby programming language for programmers already knowledgeable of various languages like Perl, Python, C++ or Java. This is also a simple collection of notes taken while learning the language.
As a reference, we just use the user's guide written by the author of ruby: matz
The syntax of the ruby programming language is somewhat similar to those of Perl and Python, but compared to the former, it has lost the C-like syntax using braces ({}) but rather than being a indentation oriented language like Python, it uses the keyword end in order to mark code sections, but it keeps the end-of-line as the marker of the end of an instruction
Both languages keep the character # to introduce a comment
up to the end of line. Note that unlike python, the
print instruction does not print a line feed,
just like it does with Perl.
We can also find the same data structures in both languages. Note that although Ruby use specific prefixes ($ and @) for some variables, it only affects their access and not their data type. Just like Perl or python, we have simple variables (integers, strings), arrays (or lists) and dictionaries (or hashes, or associative array).
Note that however, Ruby tries very hard to be an object language, so even basic types are objects, as can be seen by the following example:
As we have seen in the first example, the languages share naturally the same basic control structures, if, while, for. Note that Ruby offers various method to iterate over a collection.
Note that unlike both Perl and Python, Ruby offers a switch structure, while other languages only make use of a number of if.
One thing we left is the syntax of variables. Basic local scope variables use “simple” names, which only need to be in lowercase. Names starting with an upper case character define constants (and thus their value cannot be modified). Global variables are prefixed by the $ sign. We will come back later to this point, but member variables are prefixed by the @ sign.
With a syntax similar to the one used by Python, defining functions or procedures is done with the def keyword (and ended the usual way for Ruby blocks).
Note that you don't have to put a return statement, as Ruby will always return the last value.
Example 14. Functions returns their last expression
ruby> def foo( bar ) | 42 | end nilruby> foo 12 42
A function or method can use characters like ? or ! in their name, meaning usually that it returns a boolean (as an answer to a question) or that it modifies the object.
Example 15. Using ? and ! in function names
ruby> "foo".delete "o" "f"ruby> f = "foo" "foo"ruby> f.empty? falseruby> f.delete "o" "f" Note that the original object wasn't modified, but only the return valueruby> f "foo"ruby> f.delete! "o" "f"ruby> f "f"
A class is simply defined using the keyword class. Methods of the class are defined as functions inside its definition. Static methods are considered as methods of the class itself and not methods of the instances. To define such a method, we only need to prefix it by the name of the class.
Example 16. Defining methods
Calling this program gives:
[seb@disease] % ruby rmethods.rb
foobar
barfoo
Note also that Ruby unlike most usual languages makes heavy use of mixins: You can define a class in different parts, but you can also import inside a class a comportment defined by a module. This is most useful for using design patterns. For example, the following code sample shows how to create a simple Observer pattern.
Reading the previous example, you can see several elements of the Ruby programing language: The constructor is named initialize, you don't need to reference the current instance the class (unlike Python where you would define and use self) but when you have to, just like Python, it is called self, You create instances using the class factory method named new.
Previously, we saw that member variables are prefixed by the @ sign, but this syntax can only be used inside methods of the class. Class (or static) variables are prefixed by @@. Instance variables can't be accessed this way, but sometimes, it may be useful to add accessors to those. Instead of writing methods for each case, Ruby provides keywords: attr_reader, attr_writer, attr_accessor for read, write, and both-way access.
I won't talk here about building interfaces or programs interacting with a user, but instead I will talk about learning the language in a quick and (almost) painless way
Perl is famous for its one-liners, allowing us to write a
small (or not so small) program on the command line. It is
powerful. But it is not much interactive, you can just execute the
code. Python has a interpreter. But Python is also a reflexive
language. That means that we can observe and explore into our
objects; For example, we have a dir()
function which lists the methods and variables of an object.
Well, that is handy, but not really clean, isn't it? Ruby fancies itself to be a more object-oriented language. In fact, the Object class from which every other class inherits provides nice functions for everything you want to know about an object or class.
But the problem is that if you try to run the ruby command, it will run almost like the Perl interpreter and won't be friendly at all for interaction. Instead, for a python-like interpreter, you should use irb (which stands for “interactive ruby”).
Another good thing for Ruby is that classes are open. What does it mean? If I have a class, I can always re-enter its definition to add new methods or attributes.
Example 19. Class definition using irb
irb(main):001:0>class Fooirb(main):002:1>def bar()irb(main):003:2>endirb(main):004:1>end => nilirb(main):005:0>f = Foo.new() => #<Foo:0x326138>irb(main):006:0>f.bar => nil
So, we have defined a class with a method. But we think about it, and finally, we would like to add another method.
irb(main):007:0>class Fooirb(main):008:1>def quux()irb(main):009:2>endirb(main):010:1>end => nilirb(main):011:0>f.quux => nilirb(main):012:0>f.bar => nil
Notice how the new method is already available to our previously created object. Writing the same thing in Python, we wouldn't have the new method available in this object and any object created later would have no definition of the first class.