You are on page 1of 32

Ruby User's Guide Page 1 of 32

Ruby User's Guide


Introduction
Ruby is `an easy object oriented language'. It may seem a little strange at first, but it is designed to be
easily read and written. In this "Ruby User's Guide" you will become experienced at invoking ruby. In
addition we will sometimes delve further into ruby's nature than in the reference manual.

Table of contents
! Getting started
! Characteristics of ruby
! Simple examples
! Strings
! Regular expressions
! Arrays and associative arrays
! Simple examples again
! Control structures
! What is an iterator?
! Introduction to object orientedness
! Methods
! Classes
! Inheritance
! Redefinition of methods
! More on methods (for access control)
! Singleton method
! Modules
! Procedure objects
! Variables
! Global variables
! Instance variables
! Local variables
! Class constants
! Exception processings
! Don't forget to close the door (ensure)

Translator's note
This is translated from the original version in Japanese by matz.

Any questions for this document are welcome. There is also Ruby Language Reference Manual written by
the author of ruby. Check it out. Thanks!

Translators
GOTO Kentaro & Julian Fondren

Correspondence should be addressed to GOTO Kentaro: <URL:mailto:gotoken@notwork.org>

matz@netlab.co.jp

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 2 of 32

Getting started

First, check whether ruby is installed or not. In the following shell prompt (we denote shell prompt by `% ',
so you should not type `% '), type

% ruby -v

(`-v' tells the interpreter to print the version of ruby), then press the ENTER key. If the next message are
displayed, ruby is installed (version, date and platform may be different)

% ruby -v
ruby 1.1b5(98/01/19) [i486-linux]

When ruby is not installed, ask your administrator to install it. Of course you can do it yourself, ruby is
free software so you can get it with no cost, and you have no restrictions on installation and it's use.

Now, let's play with ruby. You can specify the program on command line with the `-e' option.

% ruby -le 'print "hello world\n"'


hello world

A program of ruby can be stored in a file of course.

% cat > test.rb


print "hello world\n"
^D
% cat test.rb
print "hello world\n"
% ruby test.rb
hello world

(^D is control-D)

Ruby has a number of command line options which may be useful. Major options are listed here:

0[DIGIT] paragraph mode


a auto split mode
c syntax checking only
e SCRIPT specifies the SCRIPT on command line
F`DELIMITOR' specifies delimitor
i[extention] in-place editing mode
I DIRECTORY specities load path
l remove NEWLINE from input and put NEWLINE to output
n automatic loop
p automatic loop with output
v prints version, verbose mode

For example,

% ruby -i.bak -pe 'sub "foo", "bar"' *.[ch]

means "replace `foo' into `bar' for all C files, preserving the original ones under name with `.bak'

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 3 of 32

appended".

% ruby -pe 0 file

`cat' whose longer name. Also it is slower than `cat' :-)

Characteristics of Ruby

We will try to list the characteristics of ruby. The catch phrase of ruby is `an interpreted scripting language
for quick and easy object-oriented programming'. Let's examine certain feautures of ruby which support
this slogan.

! quick and easy


" interpreted
" variables aren't typed

" variable declaration unnecessary


" simple syntax
" memory managing unnecessary

! for OOP
" everything is an object
" classes, inheritance, methods, etc...
" singleton method
" Mixin by module

" iterator and closure


! scripting language
" interpreter
" powerful string operations and regular expressions
" enable to access to OS directly

! misc...
" multiple precision integers
" exception processing model
" dynamic loading

Do you understand what sort of language ruby is? Don't worry about unknown concepts above since they
will be explained in this guide.

Simple examples

Now, we begin to start with a sample. First, let's consider a common example, the factorial function. The
mathematical definition of the n factorial is:

n! = 1 (n==0)

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 4 of 32

= n * (n-1)! (otherwise)

It is written in ruby as

def fact(n)
if n == 0
1
else
n * fact(n-1)
end
end

You may notice many occurrences of `end'. Someone said `Algol-like' by the historical reason. Actually,
the syntax of ruby is mimic the langage which is named Eiffel. You may also find lack of `return'. It works
since ruby's `if' has its value. Of course, appending `return' is allowed, however, in case of without `return'
it is faster rather than in case of returning by `return'.

Let's use this. Append the following line to the end of above program and save it into file, say `fact.rb'.

print fact(ARGV[0].to_i), "\n"

Here, `ARGV' is an array which contains command line argument, and `to_i' is method to convert to
integer.

% ruby fact.rb 4
24

Does it work with argument of 40? It makes the calculator overflow...

% ruby fact.rb 40
815915283247897734345611269596115894272000000000

It worked. Indeed, ruby can deal with any integer which is allowed by your machines memory. So 400 can
be obtained.

% ruby fact.rb 400


64034522846623895262347970319503005850702583026002959458684
44594280239716918683143627847864746326467629435057503585681
08482981628835174352289619886468029979373416541508381624264
61942352307046244325015114448670890662773914918117331955996
44070954967134529047702032243491121079759328079510154537266
72516278778900093497637657103263503315339653498683868313393
52024373788157786791506311858702618270169819740062983025308
59129834616227230455833952075961150530223608681043329725519
48526744322324386699484224042325998055516106359423769613992
31917134063858996537970147827206606320217379472010321356624
61380907794230459736069956759583609615871512991382228657857
95493616176544804532220078258184008484364155912294542753848
03558374518022675900061399560145595206127211192918105032491
00800000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000

We cannot check the correctness with a glance, but it must be right :-)

When you invoke ruby without an argument ruby reads a script from standard input then executes them
after the end of input.

% ruby
print "hello world\n"
print "good-bye world\n"
^D
hello world
good-bye world

However, you may want to use it as a shell. Using the following program, you can execute line by line. It

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 5 of 32

isn't necessary to understand this program.

line = ''
indent=0
print "ruby> "
while TRUE
l = gets
if not l
break if line == ''
else
line = line + l
if l =~ /,\s*$/
print "ruby| "
next
end
if l =~ /^\s*(class|module|def|if|case|while|for|begin)\b[^_]/
indent += 1
end
if l =~ /^\s*end\b[^_]/
indent -= 1
end
if l =~ /\{\s*(\|.*\|)?\s*$/
indent += 1
end
if l =~ /^\s*\}/
indent -= 1
end
if indent > 0
print "ruby| "
next
end
end
begin
print eval(line).inspect, "\n"
rescue
$! = 'exception raised' if not $!
print "ERR: ", $!, "\n"
end
break if not l
line = ''
print "ruby> "
end
print "\n"

Save this to a file `eval.rb', and run it (Actually, it is contained in `sample' directory in the source of ruby.)

% ruby eval.rb
ruby> print "hello world\n"
hello world
nil
ruby> ^D

`hello world' in the second line is output by `print' and next `nil' is returned value of `print'. `nil' means
`void (meaningless) value', it is used if the return value is not used e.g. `print'.

Anyhow, this short program is useful. Throughout this guide, `ruby> ' denotes input for this program.
(There is a program named `rbc.rb' in the sample directory, which is more useful. Please try it.)

Strings

Ruby deals with not only numerals but also strings. A string is something double-quoted ("...") or single-

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 6 of 32

quioted ('...').

ruby> "abc"
"abc"
ruby> 'abc'
"abc"

Differences between double-quoted and single-quoted are as follows. In double-quoted form, various
expressions leaded by backslash (\) are available, and also the results of evaluation are embedded for
contained expressions quoted by #{}. See examples:

ruby> "\n"
"\n"
ruby> '\n'
"\\n"
ruby> "\001"
"\001"
ruby> '\001'
"\\001"
ruby> "abcd #{5*3} efg"
"abcd 15 efg"
ruby> var = " abc "
" abc "
ruby> "1234#{var}5678"
"1234 abc 5678"

Ruby's string is smarter than C's one. For instance, concatenating is denoted by `+', repeating of n times is
denoted by `* n'.

ruby> "foo" + "bar"


"foobar"
ruby> "foo" * 2
"foofoo"

It would be written in C as follows.

char *s = malloc(strlen(s1)+strlen(s2)+1);
strcpy(s, s1);
strcat(s, s2);

We are free from even any memory management; We do not even have to consider the spaces spent by a
string.

Strings in ruby have a lot of features, while only a part of them are introduced here.

Concatenation

ruby> word = "fo" + "o"


"foo"

Repetition

ruby> word = word * 2


"foofoo"

Picking up a character (characters are integers in ruby)

ruby> word[0]
102 # 102 is ASCII code of `f'
ruby> word[-1]
111 # 111 is ASCII code of `o'

Getting substrings

ruby> word[0,1]

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 7 of 32

"f"
ruby> word[-2,2]
"oo"
ruby> word[0..1]
"fo"
ruby> word[-2..-1]
"oo"

Equality

ruby> "foo" == "foo"


TRUE
ruby> "foo" == "bar"
FALSE

Note: The above examples are results for ruby 1.0. For ruby 1.1, results are reported in lower case, i.e.,
true, false.

Now, let's make a ``pazzle'' with these features. This puzzle is `Guessing the word'. The word ``puzzle'' is
too dignified for what is to follow ;-)

words = ['foobar', 'baz', 'quux']


srand()
word = words[rand(3)]

print "guess? "


while guess = STDIN.gets
guess.chop!
if word == guess
print "you win\n"
break
else
print "you lose.\n"
end
print "guess? "
end
print "the word is ", word, ".\n"

You don't have to understand details of this program.


A result of execution is as follows. (my answer is preceeded by guess?)

guess? foobar
you lose.
guess? quux
you lose.
guess? ^D
the word is baz.

Oh, I had many mistakes despite the 1/3 probability. It is not exciting -- it is not good example...

Regular expressions

I'll try to make a more interesting pazzle. This time, we test whether or not a string matches another string,
say pattern.

In order to be useful, we import some characters with special meaning into patterns. The following are
special characters.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 8 of 32

[ ] range specification. (e.g., [a-z] means a letter


in range of from a to z)
\w letter or digit. same as [0-9A-Za-z_]
\W neither letter nor digit
\s blank character. same as [ \t\n\r\f]
\S non-space character.
\d digit character. same as [0-9].
\D non digit character.
\b word boundary (outside of range specification).
\B non word boundary.
\b back spage (0x08) (inside of range specification)
* zero or more times repetition of followed expression
+ zero or one times repetition of followed expression
{m,n} at least n times, but not more than m timesrepetition
of followed expression
? at least 0 times, but not more than 1 timesrepetition
of followed expression
| eather followed or leaded expression
( ) grouping

For example, `^f[a-z]+' means "repetition of letters in range from `a' to `z' which is leaded by `f'" Special
matching characters like these are called `reguler expression'. Regular expressions are useful for string
finding, so it is used very often in UNIX environment. A typical example is `grep'.

To understand regular expressions, let's make a little program. Store the following program into a file
named `regx.rb' and then execute it.
Note: This program works only on UNIX because this uses reverse video escape sequences.

st = "\033[7m"
en = "\033[m"

while TRUE
print "str> "
STDOUT.flush
str = gets
break if not str
str.chop!
print "pat> "
STDOUT.flush
re = gets
break if not re
re.chop!
str.gsub! re, "#{st}\\&#{en}"
print str, "\n"
end
print "\n"

This program requires input twice and reports matching in first input string to second input regular
expression by reverse video displaying. Don't mind details now, they will be explained.

str> foobar
pat> ^fo+
foobar
~~~

# foo is reversed and ``~~~'' is just for text-base brousers.

Let's try several inputs.

str> abc012dbcd555
pat> \d
abc012dbcd555
~~~ ~~~

This program detect multiple muchings.

str> foozboozer
pat> f.*z
foozboozer

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 9 of 32

~~~~~~~~

`fooz' isn't matched but foozbooz is, since a regular expression maches the longest substring.

This is too diffucult of a pattern to recognize at a glance.

str> Wed Feb 7 08:58:04 JST 1996


pat> [0-9]+:[0-9]+(:[0-9]+)?
Wed Feb 7 08:58:04 JST 1996
~~~~~~~~

In ruby, a regular expression is quoted by `/'. Also, some methods convert a string into a regular expression
automatically.

ruby> "abcdef" =~ /d/


3
ruby> "abcdef" =~ "d"
3
ruby> "aaaaaa" =~ /d/
FALSE
ruby> "aaaaaa" =~ "d"
FALSE

`=~' is a matching operator with respected to regular expression; it returns the position when matched.

Arrays and associative arrays

Ruby also deals with arrays. We can make an array by quoting with `[]'. Ruby's arrays are capable of
containing many types of objects.

ruby> ary = [1, 2, "3"]


[1, 2, "3"]

Arrays can be concatenated or repeated in the same manner as strings.

ruby> ary + ["foo", "bar"]


[1, 2, "3", "foo", "bar"]
ruby> ary * 2
[1, 2, "3", 1, 2, "3"]

We can get a part of a array.

ruby> ary[0]
1
ruby> ary[0,2]
[1, 2]
ruby> ary[0..1]
[1, 2]
ruby> ary[-2]
2
ruby> ary[-2,2]
[2, "3"]
ruby> ary[-2..-1]
[2, "3"]

Arrays and Strings are convertable. An array converts into a string with `join', and a string is split into an

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 10 of 32

array with `split'.

ruby> str = ary.join(":")


"1:2:3"
ruby> str.split(":")
["1", "2", "3"]

Assosiative arrays are another important data structure. An associative array is an array with keys which
can be valued in any way. Assosiative arrays are called hashes or dictionaries. In ruby world, we usually
use hash. A hash is constructed by a `{ }' form.

ruby> hash = {1 => 2, "2" => "4"}


{1=>2, "2"=>"4"}
ruby> hash[1]
2
ruby> hash["2"]
"4"
ruby> hash[5]
nil
ruby> hash[5] = 10 # appending value
ruby> hash
{5=>10, 1=>2, "2"=>"4"}
ruby> hash[1] = nil # deleting value
nil
ruby> hash[1]
nil
ruby> hash
{5=>10, "2"=>"4"}

Thanks to arrays and hashes, we can make data containers easily.

Simple examples again

Ok, I will give explanations for more details of ruby programming. First, we see some previous example
programs.

The following appeared in Chapter 3.

def fact(n)
if n == 0
1
else
n * fact(n-1)
end
end
print fact(ARGV[0].to_i), "\n"

Because this is the first explanation, we examine it line by line.

def fact(n)

In the first line, `def' is a statement to define a function or method. Here, it defines that the function `fact'
takes `n' as it's one argument.

if n == 0

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 11 of 32

In the second line, `if' is for checking a condition. When the condition holds execute the next line, or
execute below of `else' otherwise.

It means the value of `if' is 1 if the condition holds.

else

If the condition doesn't hold, here to `end' is evaluated.

n * fact(n-1)

When the condition is not satisfied, the value of `if' is the result of n times fact(n-1).

end

`if' statement is closed by `end'.

end

`def' statement is closed by `end' too.

print fact(ARGV[0].to_i), "\n"

This outputs the result of fact() respecting to a value specified from the command line.

ARGV is an array which contains command line arguments. The members of ARGV are strings, so we
must convert this into a integral number by `to_i'. Ruby doesn't convert strings into integers automatically
like perl does.

Next we see the pazzle appearing in the chapter on strings.

1 words = ['foobar', 'baz', 'quux']


2 srand()
3 word = words[rand(3)]
4
5 print "guess? "
6 while guess = STDIN.gets
7 guess.chop!
8 if word == guess
9 print "you win\n"
10 break
11 else
12 print "you lose.\n"
13 end
14 print "guess? "
15 end
16 print "the word is ", word, ".\n"

If you are programmer it may be clear, but here is an explanation.


In this program, a new control structure `while' is used. By `while', we execute the range up to `end' while
the condition returns true.
`srand()' in the 2nd line is to initialize for random numbers. `rand(3)' in the 3rd line returns a random
number with at most 3, i.e., `rand(3)' is valued 1,2, and 3.
In the 6th line, this program reads one line from standard input by the method `STDIN.gets'. If EOF (end-
of-line) occures while getting line, `gets' returns nil. So this `while' is to repeat until inputing `^D' (control-
D).
`guess.chop!' in the 7th line remove the last character from input. In this case, `new line' is removed.

Last, we look the program for regular expressions.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 12 of 32

1 st = "\033[7m"
2 en = "\033[m"
3
4 while TRUE
5 print "str> "
6 STDOUT.flush
7 str = gets
8 break if not str
9 str.chop!
10 print "pat> "
11 STDOUT.flush
12 re = gets
13 break if not re
14 re.chop!
15 str.gsub! re, "#{st}\\&#{en}"
16 print str, "\n"
17 end
18 print "\n"

Because `while TRUE' in the 4th line has the condition TRUE for `while' it forms an infinite loop.
However, we don't expect infinite repetition, so we put `break' in 8th and the 13th lines to escape this
`while' loop. These two `break's are also an example of the `if' modifier. An `if' modifier executes the
statement on the left hand side of `if' when the condition is preceeded by `if'

`chop!' in the 9th and the 14th lines or `gsub!' in the 15th line are method whose name contains `!'. In ruby,
we can attach `!' or `?' to end of name of method. Actually, a name of method doesn't cause any effect to
function of the method. It is a convention that we give a name with `!' to a destructive (changing state of
the receiver) mathod. Also we give a name with `?' to a predicate (returning true or false) method. For
example, `chop!' removes the last character of the string, and `gsub!' replaces the substring matching the
regular expression specified by first argument with the second argument string.

In the second argument "#{st}\\&#{en}" of `gsub!' in the 15th line, `\&' occurs. This means to expand
substring matching regular expression here. Remember that a backslash is expanded in a double-quoted
string. So one more backslash is needed here.

Control structures

This chapter shows ruby's control structures. We have seen `if', `while' and `break' already. Others are
shown here.

We know of an `if' modifier, there is also a `while' modifier.

ruby> i = 0; print i+=1, "\n" while i < 3


1
2
3
nil

We use the `case' statement to check for many options. It will be written as follows:

ruby> case i
ruby| when 1, 2..5
ruby| print "1..5\n"
ruby| when 6..10
ruby| print "6..10\n"
ruby| end

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 13 of 32

6..10
nil

where `2..5' is an expression which means the range between 2 and 5. In above example, the result of the
following expression is used to decide whether or not `i' is in the range as follows.

(2..5) === i

As this instance, `case' uses the relationship operator `===' to check for each conditions at a time. By
ruby's object oriented features, the relationship operator `===' is interpreted suitably for the object
appeared in the `when' condition. For example,

ruby> case 'abcdef'


ruby| when 'aaa', 'bbb'
ruby| print "aaa or bbb\n"
ruby| when /def/
ruby| print "includes /def/\n"
ruby| end
includes /def/
nil

tests equality as strings or string matching to regular expressions.

There are three controls to escape from a loop. `break' means, as in C, to escape from the loop. `next'
corresponds to `continue' in C, and is used for skipping the rest of loop once and going to the next
iteration. Additionally, ruby has `redo', which executes the current iteration again. The following C code is
witten in order to help C users undestand.

while (condition) {
label_redo:
goto label_next /* next */
goto label_break /* break */
goto label_redo /* redo */
;
;
label_next:
}
label_break:
;

The last way is `return'. A evaluation of `return' causes escaping. If an argument is given it will be the
return value, otherwise ruby assumes that an argument `nil' is given.

One more repetition control structure is left, that is `for'. It is used as follows.

for i in obj
...
end

The `for' statement iterates up to `end' for each elements of 'obj', with substituting each of them to the
variable `i'. This is the alternative form of the iterator, which will be mentioned later. See the following for
example of iterator.

obj.each {|i|
...
}

Both of above two forms are equivalent, but you may understand `for' more than `each'. It is one of the
reasons that `for' exists.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 14 of 32

What is an iterator?

An iterator isn't an original concept in ruby. It is a of feature CLU, which is popular among some people.
In Lisp, iterators are often used whereas they aren't called iterators. However the concepet of iterator is an
unfamiliar one for many so it should be explained in more detail.

The verb `iterate' means "do the same thing many times', you know, so `iterator' means "one which does
the same thing many times'.

Writing code, we often put loops into them in various situations. In C, we use them as `for' or `while'. For
example,

char *str;
for (str = "abcdefg"; *str; str++) {
/* process for each chars here */
}

The part of `for(...)' is a sort of idiom, but it requires some knowledge of internal data from us and is so
irksome. A programmer is required to know about internal structure when in a simple loop; That's why we
feel the language be low level. Some higher level languages have control structures to iterate. Consider the
following example of `sh'. (You may ask me, "Is `sh' higher than `C'?" Ok, it is right at least in this
problem...)

for i in *.[ch]; do
# something to do for each file
done

In this case, `sh' undertakes detailsome, pick up and substitute file names one by one. I think this is higher
level rather than C, don't you?

But there are more problems. It is good that a language deals with iterations for built-in data types, but we
are disappointed again if we must write low level loops, like in C, for data types defined by user :-( In
OOP, users often define one data type after another, so this problem is serious.

To solve above matters, every OOP language has elaborate ways to make iterations easy, for example
some languages provide class controlling iteration, etc. On the other hand, ruby allows us to define control
structures directly. In term of ruby, such user-defined control structures are called iterators.

Some examples are showed below. Ruby's string type has some iterators, so it's apt.

ruby> "abc".each_byte{|c| printf "<%c>", c}; print "\n"


<a><b><c>
nil

`each_byte' is an iterator for each character in the string. Each character is substitute into local variable `c'.
This code is translated into C as follows.

ruby> s="abc";i=0
0
ruby> while i<s.length
ruby| printf "<%c>", s[i]; i+=1
ruby| end; print "\n"
<a><b><c>
nil

The way with an iterator is simpler and probably faster. Also it seems adaptable to changes of internal
structure or different access strings.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 15 of 32

Another iterator of string is `each_line' for each line.


ruby> "a\nb\nc\n".each_line{|l| print l}
a
b
c
nil

Finding delimiters of lines, generating substrings; every irksome task is undertaken by the iterator. It's
convenient.

The `for' statement appearing in the previous chapter does iteration by way of an `each' iterator. String's
`each' works as same as `each_line', so let's rewrite the avobe example of `each_line' with `for'.

ruby> for l in "a\nb\nc\n"


ruby| print l
ruby| end
a
b
c
nil

Within `for' or an iterator, we can use a control structure `retry', it retries the loop from invoking the
iteration.

ruby> c=0
0
ruby> for i in 0..4
ruby| print i
ruby| if i == 2 and c == 0
ruby| c = 1
ruby| print "\n"
ruby| retry
ruby| end
ruby| end; print "\n"
012
01234
nil

One can define iterators in ruby. So, there are a few restrictions, but you can write your original iterators.
A definition of an iterator is common to ordinary methods.

`yield' occurs in some place in a definition of an iteretor. `yield' moves control to the block given by calling
side. The following example defines an iterator `repreat' which repeats specified times as argnument.

ruby> def repeat(num)


ruby| while num > 0
ruby| yield
ruby| num -= 1
ruby| end
ruby| end
nil
ruby> repeat(3) { print "foo\n" }
foo
foo
foo
nil

With `retry', one can define an iterator which works the same as `while', but it's not practical due to
slowness.

ruby> def WHILE(cond)


ruby| return if not cond
ruby| yield
ruby| retry
ruby| end
nil
ruby> i=0; WHILE(i<3) { print i; i+=1 }
012nil

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 16 of 32

Do you understand what an iterator is?

When one defines a new data type, it is often convenient that one defines suitable iterators too. In this
sense, above examples `repeat()' or `WHILE()' are not very useful. We will talk about practical iterators
after `class' is explained in the next chapter.

Introduction to object orientedness

"Object oriented" is a trend word. "Object oriented" anything sounds smart. Ruby is also "an object
oriented scripting language". Well, to begin with, what does "object oriented" mean?

It seems that defining OO causes arguments among even experts, probably, so everyone has slightly
different difinitions. Although if we are bothered with those differences we can't start talking, so a bold
definition is given here. "object oriented-ness" is a style of taking a point of view, (what is called
`paradigm'), in short,

a point of view centered on objects.

It is too short to understand, so let's compare it with the traditionally fashioned point of view.

According to a traditionally fashioned point of view in terms of computers, one might have considered
problems to solve as something should find the combination of `data' and `procedure' for them.

For example, one gives "an allowance data" to "a procedure calculating allowance", then one will get how
much I earn this month. This may be written programically as follows.

salary_of_this_month = allowance_function( allowance_data_of_matz )

If when one in the accounting department calculates my salary that person uses the allowance_data of my
boss to allowance_function in a mistake for mine, my salary might be increased (and someone would chew
out the accountant :-).

On the other hand, according to object oriented thinking, problems are considered through `objects' and
their `interactions'. For example, the above case, an object `allowance ledger' manages the data of basic
salary. In an object oriented way, an object is not a simple object but is smart enough to answer various
questions. To get how much my salary is this month, one may ask the ledger object, `How much is matz's
salary this month?'. Then the ledger object will give an answer based on the result of calculations of
internal data. This is sketched as follows.

salary_of_this_month = salary_ledger.salary( this_month, matz )

In this way, basic statement "asking salary_ledger" will not be changed if the internal or external way to
calcutate salary (e.g., data structure, or matz's position) will be changed in the future.

You may or may not understood the above; Any explanations are given so always, for an invisible thing
just as the sort of paradigm.

Though `a point of view with object centered' has these merits.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 17 of 32

! designers: can (or feel to be able to) design well naturally bacause of modeling by the object
corresponding to the things in the real world.
! users: (sometimes) figure out the model being similar to the real world easily. Especially, it is user-
friendly in the case of models which are effectively associated the real world.
! programmers: become robust to changing the system because of the correspondence of each
module to an object. So maintenance become easy.
! programmers: can make a new system by re-using the existing objects.

But note the above merit doesn't work in all cases. Well, any tool works "if you use it efficiently", as you
know. Object oriented thinking is not a cure-all; wrong use causes troubles.

Ok, the explanation in general is completed. See the proper books for more explanation. I wish to
recomend the suitable books if they might be in my mind. Any subjects may so; In the case of the books
about object orientedness, a precise one is difficult, but an easy one tells unsuitable or wrong things
sometimes. sigh...

Well, to return to our subject, as ruby has a title `an interpreted scripting language for quick and easy
object-oriented programming', it has many convenient features for object-oriented programming. We will
introduce them in a number of continued chapters.

Methods

An explanation for `method' has still not been given. In this section it is presented.

In the case of OOPS, asking an object for any task, the object determines the processing for itself. The
determined processing is called `method'.

In ruby, the invoking method of an object, (as it appeared many time before, you see) is formed like the
following:

ruby> "abcdef".length
6

This example means that the method named `length' of the String object "abcdef" is called.

Since each determination of the method from its called name is achieved on execution, the process may be
variant depending on the content of the variable.

ruby> foo = "abc"


"abc"
ruby> foo.length
3
ruby> foo = [1, 2]
[1, 2]
ruby> foo.length
2

The internal processes of obtaining the length are different between strings and arrays, even in such
situations ruby determines the suitable process automatically. This feature of OOPL is called
polymorphism. When an object receives unknown method an error raises.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 18 of 32

ruby> foo = 5
5
ruby> foo.length
ERR: undefined method `length' for 5(Fixnum)

So the user need know what methods are acceptable to the object, but it isn't necessary to know how the
methods are processed.

If some arguments are specified, they are surrounded by parentheses. For example:

object.method(arg1, arg2)

The parentheses can be omitted unless ambiguous. In case of the above example,

object.method arg1, arg2

means as same as the parenthesized case.

There is a special variable `self' in ruby, it is the object which call method. Callings method to self are used
very often so an abbreviation are available. `self' in

self.method_name(args...)

can be omitted then

method_name(args...)

causes same effect. What we called fuction is just this abbreviation for method calling to self. Because of
this ruby is called a pure object oriented language.

Though, functional methods behave quite similarly to the functions in other programming languages for
the benefit of those who do not grok how everything is a method.

Classes

The real world is filled by objects, and we can classify them. For example, when my one year old daughter
sees a Saint Bernard or a German shepherd, she recognizes exactly `bowwow'. How smart a pattern
recognition! Though, she may say `bowwow' when she find even a fox...

Joking aside, in terms of OOP, sort like bowwow is said `class', and on object belonging to a class is called
`instance'.

To make an object in ruby and other many OOPLs, usually, first one defines the class to determine
behavior of the object, then make it's instance that is the goal object. So let's define a class in ruby.

ruby> class Dog


ruby| def bark
ruby| print "Bow Wow\n"
ruby| end
ruby| end
nil

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 19 of 32

In ruby, class definition is a region between the keywords `class' and `end'. A `def' in class syntax defines a
method of the class.

Now we've gotten the class Dog so let's make an object.

ruby> pochi = Dog.new


#<Dog:0xbcb90>

It made a new instance of the class Doc and substituted it into the variable pochi. The method `new' of any
class makes a new instance. Because the variable pochi has properties defined in the class Dog he can
`bark'.

ruby> pochi.bark
Bow Wow
nil

Inheritance

Classification of objects takes the form of a hierarchy in most cases. For instance, `cats' are `the
mammals', and `the mammals' are `animals'. Chunks of a classification are inherited properties from basic
chunks. Again, `animals' breath therefore `cats' breath.

It is written in ruby as the follows:

ruby> class Animal


ruby| def breath
ruby| print "inhales•$B!$•(Band breaths out\n"
ruby| end
ruby| end
nil
ruby> class Cat<Animal
ruby| def bark
ruby| print "mew\n"
ruby| end
ruby| end
nil

The Cat class isn't given any definitions on how to breath, but will be inherited it from the Animal class.
Thus, in this case, the `bark' feature is just appended.

ruby> tama = Cat.new


#<Cat:0xbd80e8>
ruby> tama.breath
inhales•$B!$•(Band breaths out
nil
ruby> tama.bark
mew
nil

Though, the properties of the basic class (called parent class or superclass) are not always inherited to its
derivative classes (children class or subclass). For instance, `birds' fly while `penguins' don't. In other
words, penguins have most other properties (`laying the eggs', etc.) of birds except flying. It will be
redefined.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 20 of 32

Let's express in ruby:

ruby> class Bird


ruby| def lay_egg
ruby| # do something ..
ruby| end
ruby| def fly
ruby| #...
ruby| end
ruby| #...
ruby| end
nil
ruby> class Penguin<Bird
ruby| def fly
ruby| fail "Penguins can't fly"
ruby| end
ruby| end
nil

The above case will be written as something like this. However, I feel that it is not suitable to write
knowledgebase-some in ruby.

Using inheritance with defining the common properties in superclass, we need only to append or to
redefine the differences. Someone call a programming style like it `differential programming'. It is one of
the merits of OOP.

Redefinition of methods

In subclass, we get changing behavior of the instances by redefine the superclass methods. See the
following example:

ruby> class Human


ruby| def print_id
ruby| print "I'm a man-kind.\n"
ruby| end
ruby| def train_toll(age)
ruby| print "reduced-fare.\n" if age < 12
ruby| end
ruby| end
nil
ruby> Human.new.print_id
I'm a man-kind.
nil
ruby> class Student1<Human
ruby| def print_id
ruby| print "I'm a student.\n"
ruby| end
ruby| end
nil
ruby> Student1.new.print_id
I'm a student.
nil

ruby> class Student2<Human


ruby| def print_id
ruby| super
ruby| print "I'm a student too.\n"
ruby| end
ruby| end

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 21 of 32

nil
ruby> Student2.new.print_id
I'm a man-kind.
I'm a studnet too.
nil

In the redefinition, the original method of superclass can be called by `super', and the arguments of `super'
are taken over to the original method if they are given.

ruby> class Student3<Human


ruby| def train_toll(age)
ruby| super(11) # unconditionally reduced
ruby| end
ruby| end
nil
ruby> Student3.new.train_toll(25)
reduced-fare.
nil

Well, it is probably not a good example. I hope you know now how redefinitions are done.

More on methods (for access control)

In the previous chapter, we said that ruby has no function, but it does have what is called a method.
Though, there are several sorts of methods so it is a little complicated. These the sorts of mothods are
named `access controls', which play the roll of the restriction in method calling.

First, defining the function (method) in the top level,

ruby> def sqr(n)


ruby| n * n
ruby| end
nil
ruby> sqr(5)
25

`def' appearing outside of class definition acts to append a method to the Object class. The Object class is
inherited by all other classes, so it means that sqr can be used in all the classes.

Now the all classes must be able to call sqr, then we try to call sqr to `self':

ruby> self.sqr(5)
ERR: private method `sqr' called for main(Object)

Oh, an error occurred... that was not how we understood it!

The fact is that the methods defined in the top level can be called with only function call style. It is the
conclusion of the policy: "What method looks function must behave function".

So it causes a different error message than when undefined methods are called.

ruby> undefined_method(13)
ERR: undefined method `undefined_method' for main(Object)

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 22 of 32

Aha! that isn't `undefined' but `private'. Conversely, methods which are defined in a class can be called
freely.

ruby> class Test


ruby| def foo
ruby| print "foo\n"
ruby| end
ruby| def bar
ruby| print "bar -> "
ruby| foo
ruby| end
ruby| end
nil
ruby> test = Test.new
#<Test:0xbae88>
ruby> test.foo
foo
nil
ruby> test.bar
bar -> foo
nil

In the above example, the `bar' method calls `foo' in function style.

If a method is called in function style only, the calls are within the class or the its subclass, so it works like
a `protected' method in C++. In other words, we may forbidden to access from outside.

To change the accessible property of a method, we use the methods `private' and `public'.

ruby> class Test2


ruby| def foo
ruby| print "foo\n"
ruby| end
ruby| private :foo
ruby| def bar
ruby| print "bar -> "
ruby| foo
ruby| end
ruby| end
nil
ruby> test2 = Test2.new
#<Test2:0xbb440>
ruby> test2.foo
ERR: private method `foo' called for #<Test2:0x8a658>(Test2)
ruby> test2.bar
bar -> foo
nil

Adding the `private :foo' line, you see that the foo method isn't available with `test.foo'.
Additionally, to open a method which was made `private', use `public :the_method_name'. Don't forget the
colon `:' leading the method name when you specify. If you missed putting `:' the following literal is
regarded as reference to a local variable but not as a method name, and it makes complicated errors.

A private method warks similarly to what we call function. Though, yet it is very much a method, so the
methods with same name are allowed between defferent classes; That is a disparity against the concept of
ordinary function.

Singleton method

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 23 of 32

The behavior of an instance is determined by the class, but we know that a particular instance should have
special behavior. In most languages, we must make another class for the instance, while in ruby we can
append methods to a paticular instance without such tiresomes.

ruby> class SingletonTest


ruby| def size
ruby| print "25\n"
ruby| end
ruby| end
nil
ruby> test1 = SingletonTest.new
#<SingletonTest:0xbc468>
ruby> test2 = SingletonTest.new
#<SingletonTest:0xbae20>
ruby> def test2.size
ruby| print "10\n"
ruby| end
nil
ruby> test1.size
25
nil
ruby> test2.size
10
nil

In this example, test1 and test2 belong to same class, though, test2 has a redefinition of the `size' method
and they behave differently. Such a method of a particular instance is called `singleton method'.

The singleton methods are used in the cases of, for example, buttons of GUI, which has different action
for the press event. In this case, we may redefine the action suitably for each button object.

The concept of the singleton method is not original to ruby, as it appears in few other languages other than
ruby, such as CLOS, Dylan, etc. Also, some languages, for example, Self and NewtonScript, have the
singleton methods only. Such are called `prototype-base' languages.

Modules

Ruby has also the `module'. Modules in ruby are very similar to classes but there exist the following three
differences:

1. The module has no instance.


2. The module has no subclass.
3. The module is defined by module ... end.

Actually, the Module class of module is the superclass of the Class class of class.

Now, roughly saying, there are two uses of the module. First, to collect the methods or the constants. For
example, the Math module in standard library plays such a roll.

ruby> Math.sqrt(2)
1.41421
ruby> Math::PI
3.14159

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 24 of 32

Oh, I have given no explanation for `::'; It is the operator to refer the constants of a module or a class.
When we refer directly to the methods or the constants of a method, we use the `include' method.

ruby> include Math


Object
ruby> sqrt(2)
1.41421
ruby> PI
3.14159

Another use of the module is called `mixin'. This use is little complex so should be explained in detail.

Some Object-Oriented programming langages other than ruby have the feature to realize inheritance from
plural superclasses (this feature is called multiple-inheritance). Though, ruby purposely doesn't have this
feature. In the altanative way, we can make it by mixin with the module.

As said above, the module is works like the class; The methods or the constants of a module can't be
inherited but be appended to other modules or classes by use of include. So, doing include the definition of
a module, we can mix the property into the class. It is called mixin.

Enumerable are the instances of mixin appearing in the standard library. By mixin this module to a class
whose the `each' method returns each element, the class get the features: `sort', `find', etc.

The following differaces exist between multiple-inheritance and mixin:

! The module don't generate instance; It is grantee for the abstract class.
! The module keeps the relationship of instance to be a tree.

Each of them inhibit complexty of the relationships among the classes. It is because of ruby doesn't have
multiple-inheritance. Imagine the situation that the classes has many superclasses and the relationship of
instance forms of a network. Situations like this are too complex to understand for the brain of the human
being, at least my brain...

On the other hand, mixin makes it simple as just `the collection of particular properties all we wanna add'.

So, even in the language with multiple-inheritance, it is considered that the smart way is virtually mixin by
multiple-inheriting classes like a collection of abstract properties. We advanced this idea in ruby, by
deleteing multiple-inheritance and allowing mixin only.

Procedure objects

When one is programming one often want to send a procedure as argument of the method. For instance,
when one is writing something to process the signals. It may be convenient if the procedures can be
specifed as arguments for each arrivals of signals.

To specify the process for signals, use the `trap' method in ruby.

ruby> trap "SIGUSR1", 'print "foobar\n"'


nil
ruby> Process.kill "SIGUSR1", $$
foobar

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 25 of 32

There is specified the process for arrival of the signal `SIGUSR1' by the string here. It is the way owing to
ruby's nature of being an interpreter. Though, through no strings, one can let the procedure affect an object
directly.

ruby> trap "SIGUSR1", proc{print "foobar\n"}


nil
ruby> Process.kill "SIGUSR1", $$
foobar
1

The `proc' method generates a `procedure object' from the region within the braces {}. To execute the
procedure object, one can use the `call' method.

ruby> proc = proc{print "foo\n"}


#<Proc:0x83c90>
ruby> proc.call
foo
nil

As the handler or the call-back, the uses of the procedure objects are similar to the function pointers in C.
We are free from defining any functions or methods for these purposes (also free from naming), it may be
convenient. •$B$J$$!%•(B

Variables

Ruby has three sorts of variables, one sort of constant and two sorts of pseudo-variables. The variables and
the constants have no type. There are also demerits due to non-typed variable, however, it seems to fit to
`easy programming' as ruby aiming.

One can obtain the sort of variable and constant by its name. It is one of the features of ruby, the name
tells that it is a variable or a constant, so we don't need declarations and one can tell the sort apart with a
glance. This feature is convenient for programming, but it may cause another problem to make finding
typo difficult.

The sort is told by the first character of the name. The following give the correspondings.

$ global variable
@ instance variable
[a-z] local variable
[A-Z] constant

The exception of the above rule is in the case of pseudo-variable. Nonetheless the pseudo-variable looks as
same as the local variable, it is the constant in the fact. There are only two sorts of the pseudo-variables, so
I guess you will never confuse them.

self the object executing currently


nil `meaningless' value (for false)

Let's see few example.

ruby> self
main

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 26 of 32

ruby> nil
nil

`main' is the object of the top-level. The value of `self' inside each method may be different. The pseudo-
variables are eventually the constants, so substitutions into `self' or `nil' are forbidden.

Global variables

A global variable has `$'-prepended name and it can be referred from anywhere in the program. Before
initialization, the global variable has a special value `nil'.

ruby> $foo
nil
ruby> $foo = 5
5
ruby> $foo
5

One can refer and change the global variable, so, it means that careless uses are dangerous because the
effects are spread program-wide. You should not use it often. If you use it, you should name it redundantly
to not be coincide to another one (it is because of the above naming `$foo' is bad example).

One can trace the global variable. So, you can specify the procedure which is invoked when the value of
the global value is changed.

ruby> trace_var :$x, proc{print "$x = ", $x, "\n"}


nil
ruby> $x = 5
$x = 5
5

As the above example, for a variable working as a trigger which invoke a procedure when the variable is
chaged, we often call such a variable an `active variable'. For instance, it is useful for displaying the
current value whenever it is changed in the case of a GUI.

In global variables, most names with one letter following `$' are known as system variables and have
special meanings. For example, `$$' is referred as the process id of the ruby interpreter and it is read-only.
The following list are major system variables:

$! error message
$@ position of an error occurrence
$_ latest read string by `gets'
$. latest read number of line by interpreter
$& latest matched string by the regexep.
$1, $2... latest matched string by nth parentheses of regexp.
$~ data for latest matche for regexp
$= whether or not case-sensitive in string matching
$/ input record separator
$\ output record separator
$0 the name of the ruby scpript file
$* command line arguments for the ruby scpript
$$ PID for ruby interpreter
$? status of the latest executed child process

In the above, `$_' and `$~' are treated as local scope. So, it doesn't influence outside the method even if the
value is changed. These should be remarked as exceptions.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 27 of 32

Instance variables

Instance variables are specified by `@'-prepended name. Instance variables are unique for the object which
is referred by `self'. Any different object has a different value for the instance variables if even the objects
belong to same class. Instance variables cannot be read or changed from the outer objects, so, one must do
it via a method. The value of an uninitialized instance variable is `nil'.

Instance variables of ruby do not need declaration. This implies a flexible structure of objects. The
instance variables of ruby, indeed, are dynamically appended.

ruby> class InstTest


ruby| def foo(n)
ruby| @foo = n
ruby| end
ruby| def bar(n)
ruby| @bar = n
ruby| end
ruby| end
nil
ruby> i = InstTest.new
#<InstTest:0x83678>
ruby> i.foo(2)
2
ruby> i
#<InstTest: @foo=2>
ruby> i.bar(4)
4
ruby> i
#<InstTest: @foo=2, @bar=4>

Local varables

Local variables are specified by a name which is prepended with lower case letter or `_'. Let's see the
following example.

ruby> foo
ERR: undefined local variable or method `foo' for main(Object)

What!? I got an error!!

The fact is that local variables need to be initialized by substitution differently from other type of
variables, because the first substitution works similarly to declaration. When an undefined local variable
are referred, it is regarded as an invoking of method without any arguments. So you got the error message,
`undefined local variable or method'.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 28 of 32

But you don't need to substitute arguments of a method in any definitions for methods, because their
variables are considered as not yet being substituted.

The scope of a local variable is

! class ... end


! module ... end
! def ... end
! through the program (unless aboves)

A local variable in an iterator block is effective only in the block if it is substituted in the block for the first
time.

ruby> i0 = 1; print i0, "\n"; defined? i0


1
"local-variable"
ruby> loop{i1=5; print i1, "\n"; break}; defined? i1
5
FALSE

In the above, `defined?' is an operator which checks whether its argument is defined or not. As you see, a
variable `i1' that is substituted in loop for the first time is undefined after exiting the loop.

Procedure objects sharing their scope share also local variables.

ruby> i=0
0
ruby> p1 = proc{|n| i=n}
#<Proc:0x8deb0>
ruby> p2 = proc{i}
#<Proc:0x8dce8>
ruby> p1.call(5)
5
ruby> i
5
ruby> p2.call
5

A peculiar point to procedure objects is that sharing local scope is continued out of the scope. So, the local
variable `i' is shared even if `p1' and `p2' are passed to outside of the scope (In this case, `i' can be access
from `p1' or `p2'). See the followings:

ruby> def foo


ruby| i = 15
ruby| get = proc{i}
ruby| set = proc{|n| i = n}
ruby| return get, set
ruby| end
ruby> p1, p2 = foo
#<Proc>, #<Proc>
ruby> p1.call
15
ruby> p2.call(2)
2
ruby> p1.call
2

Class constants

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 29 of 32

The next topic is class constants. A constant is specified by a capitalized name, and is defined by a
substitution. An access of an undefined constant or a substitution to a defined constant causes an error.

ruby> FOO
ERR: Uninitialized constant FOO
ruby> FOO = 5
5
ruby> FOO
5
ruby> FOO = 5
ERR: already initialized constnant FOO

Constants are referred in a class/module scope. In other words, one can refer to a constant of the class
(even of the parent class or the included module) or module definition.

ruby> module ConstTest


ruby| CONST1 = 1
ruby| CONST2 = 3
ruby| CONST3 = 5
ruby| print CONST1, CONST2, CONST3, "\n"
ruby| def const_test
ruby| print CONST3, CONST2, CONST1, "\n"
ruby| end
ruby| end
135
nil
ruby> include ConstTest # makes consts be referred
Object
ruby> CONST1
1
ruby> CONST1 = 9 # can redefine consts of the ancestor (but should not)
9
ruby> const_test # the above didn't affect to the ancestor's
531

One can refer to constants of a class via the `::' operator.

ruby> ConstTest::CONST1
1

But a substitution with `::' is not allowed.

ruby> ConstTest::CONST1 = 7
ERR: compile error in eval():
eval.rb:33: parse error
ConstTest::CONST1 = 7
^

Also, the `::' operator is available for a constant which is defined in the class or module; In the above, the
constants CONST1, CONST2 and CONST3 can be refered to with `::' for the ConstTest module, but one
can not refer CONST2 or CONST3 of an object of the class which include the ConstTest module
(however CONST1 can be referred, as it is redefined in the class).

Exception Processings

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 30 of 32

The execution and the exception always go together. Opening a file, the file may not exist; Writing a file,
the disk may be full. A program is considerd to be of bad quality if it discounts these exceptions.

It is tiresome that we cannot know the occurrence without checking ``Was the process okay?'' each time.
Some problems will certainly be caused if the continuation runs with the appropiate processes omitted for
an exception. When an exception occurs the process should not go without coping with it.

In ruby, an exception occurs in such exceptional situations. If nothing copes with them, the exception
stops the program. So we don't have to worry about running without exception processing.

ruby> file = open("/unexistant_file")


ERR: No such file or directory - /unexistant_file

In C, the programmer must check for each critical situation, such as whether a file was opened or not. On
the other hand, in ruby, we may assume `Since no exception occured the process succeeded'. The above
ruby code must be written as follows in C:

FILE *file = fopen("/unexistant_file", "r");


if (file == NULL) { /* error recovery */ }

This shows that the ruby version is simpler because error processing is unnecessary.

As explained above, the program stops if an exception occurs. But it is usually not good: In the most cases,
you want to continue the execution after some processings to cope with the cause of the exception. For
such treatments, you should capture the exception by using `begin'. The following demonstrates this:

ruby> begin
ruby| file = open("/unexistant_file")
ruby| rescue
ruby| file = STDIN
ruby| end
#<IO:0x93490>
ruby> print file, "==", STDIN, "\n"
#<IO:0x93490> == #<IO:0x93490>
nil

You can see that `STDIN' is substituted to `file' because `open' failed.

`begin' moves control to error proccessing which follows `rescue'.

`Retry' is available for `begin' by `retry'. In a rescue, `retry' moves the control to the
beginning of the `begin'. See an application below.

ruby> fname = "unexistant_file"


ruby> begin
ruby| file = open(fname)
ruby| # something to use file
ruby| rescue
ruby| fname = "existant_file"
ruby| retry
ruby| end
#<File:0x68890>

It failed opening a file and substituted another file name to fname, then
retried. The following is the flow of the process:

! an exception occured at open


! went to rescue. fname was re-substituted
! by retry went to the beginning of the begin
! this time open succeeded
! continued the essential prosess.

Notice that if the file of re-substituted name does not exist this example code

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 31 of 32

retries infinitely. Be careful if you use `retry' for an exception process.

Every ruby library raises an exception if any error occurs, and you can raise
exceptions. To raise an exception use `raise'. raise takes one string argument
as a message which explains the error. This argument can be omitted (but should
not be omitted), and this error message can be accessed by `$!' later.

ruby> raise "test error"


ERR: test error
ruby> begin
ruby| raise "test2"
ruby| rescue
ruby| print $!, "\n"
ruby| end
test2
nil

Don't forget to close the door (ensure)

Some processes need to be finished up. For example, we should close an opened
file, flush data which is stored in the buffers, etc. If there is only one exit
for each method, we may put anything to be done there, however, a method
returns from various conditions and we must consider the alternative way to
ensure finishing the process. Ruby also has `exception', which increases the
way to return. See the following for instance:

ruby> begin
ruby| file = open("/tmp/some_file", "w")
ruby| # something to do
ruby| file.close
ruby| end

In the above, if an exception occurred while ``something to do'' the file will
be left open. Though the file should be closed, we don't want the following:

ruby> begin
ruby| file = open("/tmp/some_file", "w")
ruby| # something to do
ruby| file.close
ruby| rescue
ruby| file.close
ruby| fail # raise an exception
ruby| end

It is too complicated to write, and one must respond for each return or break.

For such situations, ruby has a syntax to describe a finishing up. If an ensure
clause is put in begin, the clause is executed always.

ruby> begin
ruby| file = open("/tmp/some_file", "w")
ruby| # something to do
ruby| ensure
ruby| file.close
ruby| end

The section specified by ensure is sure to be executed, so the programmer


doesn't need to worry to close the file.

By the way, if one specifies both rescue and ensure in a begin, the rescue must
go ahead of the ensure.

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00
Ruby User's Guide Page 32 of 32

file://I:\misc\applications\Ruby\ruby-uguide\all.html 28-Dec-00

You might also like