では,rubyによるプログラミングを解説しよう.まず,既に出てい るいくつかのプログラムをみて,学ぶことにしよう.
まず,3章に出たfact.rbというプログラムを見てみよう.
def fact(n) if n == 0 1 else n * fact(n-1) end end print fact(ARGV[0].to_i), "\n"
最初なので1行ずつ解説することにしよう.
def fact(n)
1行目の`def'というのは関数やメソッドを定義する文だ.ここでは factという関数を定義していて,nという引数が1つあると宣言して いる.
if n == 0
2行目の`if'は条件判断だ.条件が成立すれば次の行を,不成立な ら`else'以降を実行する.
1
条件が成立した時の`if'全体の値は1であることを示している.
else
条件が不成立の時には,ここから`end'までを実行する.
n * fact(n-1)
条件が不成立の時の値は,変数nの値にfact(n-1)の値をかけたもの である.
end
`if'文は`end'で終る.
end
`def'文も'end'で終る.
print fact(ARGV[0].to_i), "\n"
コマンドライン引数で指定した値に対するfact()の結果を出力する. printは明示的に改行する必要があることに注意して欲しい.
ARGVはコマンドラインの引数の入っている配列である.これには文 字列で入っているので,`to_i'というメソッドで数字に変換してや る必要がある.rubyではperlのような文字列から数字への「適当な 変換」は行われない.
次は文字列のところに出て来たパズルのプログラムだ.
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"
プログラムを組んだことのある人ならすぐに意味が分かるような気がするが,
一応説明しておこう.
このプログラムには新しい制御構造である`while'が使われている.
'while'は条件が成立するまで endまでの間を繰り返し実行するものだ.
2行目の'srand()'は乱数の初期化,3行目の'rand(3)'は3を越えない範囲
(0,1,2のいずれか)の乱数を返す.
6行目を見ると'STDIN.gets' というメソッドで標準入力から一行読み込んでいる.
'gets'はEOFに出会うとnil (偽)を返すので,`^D'が入力されるまで繰り返すことになる.
7行目の 'guess.chop!' は、入力した文字列の最後の文字(この場合は改行)を
取り除いている。
最後に正規表現のプログラムを見てみよう.
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"
4行目の`while TRUE'は`while'の条件式がTRUE(真)なので,無限ルー プを構成している.本当に無限ループになっては困るので,8行目, 13行目の`break'で脱出するようになっている.8行目,13行目は更 に`if'修飾子の例にもなっている.`if'修飾子は`if'の後ろの条件 が成立する時,その前の文を実行する.
9行目,14行目の`chop!'や15行目の`gsub!'は`!'を含む名前を持つ メソッドである.rubyではメソッド名の終りに`!'と`?'をつけるこ とができる.名前によってメソッドの機能は変わらないが,慣習と して,破壊的な(レシーバの状態を変える)性質を持つメソッドは `!' のついた名前を,述語(真偽値を返す)メソッドには`?'をつけ ることになっている.たとえば,`chop!'は文字列の最後の文字(こ の場合は改行)を取り除くメソッドであり,`gsub!'は第一引数の 正規表現に一致する部分を第二引数の文字列で置き換えるメソッドで, どちらも元の文字列を変更する.
15行目の`gsub!'の第二引数 "#{st}\\&#{en}" に '\&' という部分がある. これは元の文字列中の正規表現にマッチした部分をここに展開しろというgsub!への 指定だ.文字列を "" でくくる場合,バックスラッシュ(\)の展開をするので, 一個余分に \ が必要だ.