User Guide

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View User Guide as PDF for free.

More details

  • Words: 9,358
  • Pages: 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: [email protected]

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

= n * (n-1)!

Page 4 of 32

(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

[ ] \w \W \s \S \d \D \b \B \b * + {m,n} ? | ( )

Page 8 of 32

range specification. (e.g., [a-z] means a letter in range of from a to z) letter or digit. same as [0-9A-Za-z_] neither letter nor digit blank character. same as [ \t\n\r\f] non-space character. digit character. same as [0-9]. non digit character. word boundary (outside of range specification). non word boundary. back spage (0x08) (inside of range specification) zero or more times repetition of followed expression zero or one times repetition of followed expression 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> 3 ruby> 3 ruby> FALSE ruby> FALSE

"abcdef" =~ /d/ "abcdef" =~ "d" "aaaaaa" =~ /d/ "aaaaaa" =~ "d"

`=~' 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 + [1, 2, "3", ruby> ary * [1, 2, "3",

["foo", "bar"] "foo", "bar"] 2 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. 1

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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

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"

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 (endof-line) occures while getting line, `gets' returns nil. So this `while' is to repeat until inputing `^D' (controlD). `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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Page 12 of 32

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"

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> ruby| ruby| ruby| ruby| ruby|

case i when 1, 2..5 print "1..5\n" when 6..10 print "6..10\n" 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 goto label_break goto label_redo ; ; label_next: } label_break: ;

/* next */ /* break */ /* redo */

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" 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"
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 userfriendly 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 #

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
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 rel="nofollow"> tama = Cat.new # 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
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> ruby| ruby| ruby| ruby| ruby| ruby| ruby| nil ruby> I'm a nil ruby> ruby| ruby| ruby| ruby| nil ruby> I'm a nil

class Human def print_id print "I'm a man-kind.\n" end def train_toll(age) print "reduced-fare.\n" if age < 12 end end Human.new.print_id man-kind. class Student1
ruby> class Student2
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 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 # 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 # ruby> test2.foo ERR: private method `foo' called for #(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

1

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"} # 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. $ @ [a-z] [A-Z]

global variable instance variable local variable 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 nil

the object executing currently `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 pseudovariables 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: $! $@ $_ $. $& $1, $2... $~ $= $/ $\ $0 $* $$ $?

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. 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 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 # ruby> i.foo(2) 2 ruby> i # ruby> i.bar(4) 4 ruby> i #

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} # ruby> p2 = proc{i} # 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 #, # 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 # ruby> print file, "==", STDIN, "\n" # == # 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 # 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

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

Page 32 of 32

28-Dec-00

Related Documents

User Guide
April 2020 41
User Guide
July 2020 29
User Guide
November 2019 71
User Guide
May 2020 41
User Guide
June 2020 31