- コピー - - 目次

簡単なプログラム


では,簡単なプログラムを通じてrubyの実際を学ぶことにしよう. まず,"hello world"の次にありふれた例題として階乗の計算を考 えてみる.階乗n!の数学的定義は以下の通りだ.


  n! = 1                (n==0)
     = n * (n-1)!       (それ以外)

これをrubyで書くと,

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

となる.`end'がやたら多いのが目立つが,これを歴史的な理由か ら「Algolっぽい」と呼ぶ人が多い.実はrubyのこの辺の文法は Eiffelという言語の真似だ.returnがないことに気が付いた人もい るかもしれない.rubyのifは値をとることができる式なので,これ で大丈夫なのだ.もちろんreturnがあっても構わない.細かいこと をいうと,returnが無い方がちょっとだけ実行速度が速いようだ.

では,実際に計算してみよう.上のプログラムに次の行を加えて fact.rbというファイルにしまってrubyを呼び出そう.

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

ARGVはコマンドラインの引数が入っている配列,`to_i'は文字列を 整数に変換するメソッド(手続き)だ.


 % ruby fact.rb 4
 24

では,4を40にしてみよう.普通の電卓ならオーバーフローしてし まう数だ.


 % ruby fact.rb 40
 815915283247897734345611269596115894272000000000

ちゃんと出る.実はrubyはメモリが許す限りの大きさの整数を扱う ことができるのだ.だから400!でも計算できる.


 % ruby fact.rb 400
 64034522846623895262347970319503005850702583026002959458684
 44594280239716918683143627847864746326467629435057503585681
 08482981628835174352289619886468029979373416541508381624264
 61942352307046244325015114448670890662773914918117331955996
 44070954967134529047702032243491121079759328079510154537266
 72516278778900093497637657103263503315339653498683868313393
 52024373788157786791506311858702618270169819740062983025308
 59129834616227230455833952075961150530223608681043329725519
 48526744322324386699484224042325998055516106359423769613992 
 31917134063858996537970147827206606320217379472010321356624 
 61380907794230459736069956759583609615871512991382228657857 
 95493616176544804532220078258184008484364155912294542753848 
 03558374518022675900061399560145595206127211192918105032491 
 00800000000000000000000000000000000000000000000000000000000 
 0000000000000000000000000000000000000000000

大きすぎて良く分からないが,きっとちゃんと計算しているに違い ない.

rubyを引数無しで起動すると標準入力からスクリプトを読み込んで, 最後にまとめて実行する.


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

しかし,シェルのように1行ずつ実行できた方が便利な時もある. 以下のプログラムを使えば,とりあえず1行ずつ実行できる.この プログラムが何をやっているかは今は分からなくても問題ない.


 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"

これをeval.rbというファイルに保存して,実行してみよう.
(実は、rubyのソースセットの sample ディレクトリにちゃんと入っているから そっちを使ってもいい.)


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

最初の`hello world'がprintによる出力で,次のnilがprintの戻り 値だ.nilってのは,「意味が無い(重要でない)値」という意味で, 戻り値を使うことの無いprintのようなメソッドはこの値を返すこ とが多い.

ともかく,この小さなプログラムは結構便利だ.今後は`ruby> 'と いうプロンプトで,このプログラムへの入力を表すことにしよう.
(実は、ruby 1.1 の sample ディレクトリにはもっと便利な rbc.rb というのも 入っている.)


- コピー - - 目次