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