Ruby Users' Guide - 簡単なプログラム

前 - コピー - 次 - 目次

### 簡単なプログラム

では，簡単なプログラムを通じて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 というのも 入っている.)

前 - コピー - 次 - 目次