2008-08-11

The second step

Real programs
Time to write another post, probably. Now that you have already your console set up, I will tell you (or maybe you already know it?) how to write (sort of) real programs - Ruby programs that you can run by clicking their icon or entering their names.
It's very simple: just open SciTE - the text editor that came with the Ruby installation, write a program (no int main(){ ... return 0;}, just write your code just like in the console), and save it as an .rb file anywhere on your hard drive. Then go to this directory and double-click the file. If your Ruby is installed properly, it should run in a new console window, just as .bat or other batch files do. (If you see just a blink of a console, add
gets
command at the end of your program so that it waits for Enter.) If it doesn't work then you can instruct your system to open this kind of file with ruby.exe which is located in your C:\Ruby\Ruby\bin directory (if you followed my advise from the previous post).

I'd suggest you to put your programs under C:\Ruby\Programs, each program in a separate directory, even if they consist of just one .rb file, as your first programs probably do. It helps keeping things tidy later.

Hmm, what to write now?
OK, why I'm talking all around the language, but have not given you a slightest hint I really know how to write a Ruby program? OK, let's have a look at a code snippet here:

"Ruby - Al2O3::Cr".scan(/./).each_with_index{|c,i| puts "%2d: %s (%3d)"%[i,c,c[0]]}

Do you know what it does, at a first glance? If no, then note my words now: in a moment you're going to gain a nice piece of knowledge. The Ruby learning curve is very pleasant - things look terribly complicated until you finally get to them and they turn out to be very easy and nice. Let's analyse the line, function by function.

"Ruby - Al2O3::Cr"
- we create a String object containing exactly what you see. A bonus knol about Strings: to have a quote mark in a String, prepend it with backslash, like this:
"This is quoted: \"abc\"."
. To get a backslash, write a double backslash. To get a line end, write
"\n"
.

aString.scan(/./)
- here we call the method scan of a string. This method takes a regular expression and returns an Array of all parts of the string that match the regular expression. Regular expressions in Ruby are enclosed within slashes. A dot means any single character. So - finally - the result of the function will be an Array, each element of which will be a single character from the string. If you're not sure if you understand, write
"Ruby - Al2O3::Cr".scan(/./)
in irb and everything will become clear. So now we have an Array of single characters.

anArray.each_with_index
- this method takes a closure - the thing in the curly brackets, and does with it what the method name says: calls it with each element and its index. So if your closure looks like the one in the example above, then it will be called once for each element in the array (total of 15 times here), and each time the variables
c
and
i
inside the closure will have different values: first time
c="R"
and
i=0
, second time
c="u"
and
i=1
, third time
c="b"
and
i=2
... got it? I hope so.

Inside the closure we execute this:
puts "%2d: %s (%3d)"%[i,c,c[0]]
. (It means that the puts command will be executed 15 times, as already said). And the argument to the command is
"%2d: %s (%3d)"%[i,c,c[0]]
, which might look a bit complicated at first, but which is not complicated at all. Just type in irb something like
"a%db"%5
and see what comes out. Now try
"%3d"%5
, or
"%03d"%5
, or
"%.2f"%5.6
. Now you can try with more % fields in the string:
"-%d-%s-"%[15,"xx"]
. As you see, all that changes is that now you have to pass an Array of values to insert into % fields. So please, remember this useful operation:
aString%anArray
makes more or less the same as the old sprintf, only nicer!

Back to our formula, we output here three arguments, and Integer (%d), a String (%s) and another Integer, for which we pass
c[0]
. This might need a bit of your attention, as it's a small gotcha in Ruby: the square bracket on a String does not extract a character from the given index, it extract the code of the character. So that's the easiest way to convert the variable c (which is a single character, as you surely remember) into its ASCII code. Note that this is going to change in Ruby 1.9!

OK, that's it. Even if you feel like you haven't learnt a lot today, please stay tuned for the next part, which is going to be a bit more interesting! We're going to tackle classes.

If you have some free time and want to learn something by yourself, register on DonationCoder and go to Ruby Programming School. It's a nice place to prove you've learnt something today!

No comments: