[ruby-list:19] tutorial for 0.93b

From: matz@... (Yukihiro Matsumoto)
Date: 1995-12-22 09:02:48 UTC
List: ruby-list #19
まつもと ゆきひろ@トヨタケーラムです.

テュートリアルの書けたところまでを投稿します.文体は河野さん
の「入門Perl」(アスキー)の真似です.

--
Ruby入門

* はじめに

Rubyは「お手軽オブジェクト指向言語」だ.ちょっと独特ではある
が,慣れれば書きやすく,ある程度は読みやすいようにできている.
この「Ruby入門」では実際にrubyを動かしてみながらrubyに慣れる
ことにしよう.

* 起動してみる

とりあえず,rubyが用意されているか調べてみよう.シェルのプロ
ンプトが出ている状態で

 % ruby -v

と入力して(`-v'はバージョンを表示するオプションだ),リターン
キーを押して,

 ruby version 0.95b (95/12/22)

と表示されたら(バージョンや日付は違うかもしれない),rubyがちゃ
んとインストールされている.インストールされていなかったら,
誰かに頼んでインストールしてもらおう.もちろん自分でインストー
ルしても良い.

では,ちょっとrubyを使ってみよう.`-e'オプションで,rubyのプ
ログラムを直接指定できる.

 % ruby -le 'print "hello world\n"'
 hello world

こんな感じだ.rubyのプログラムはもちろんファイルにしまうこと
もできる.

 % cat test.rb
 print "hello world\n"
 % ruby test.rb
 hello world

rubyにはいろいろなオプションがあるので,使いこなせば便利にな
ることも多い.perlと大体同じだというと分かる人には分かるかも
しれない.主なものを一通り紹介しておこう.

	-0[数字]	パラグラフモード
	-a		オートスプリットモード
	-c		文法チェック
	-e スクリプト	コマンドラインからスクリプトを指定
	-F区切り	区切り文字(列)を指定
	-i[拡張子]	その場編集
	-I ディレクトリ	ロードパスの指定
	-l		入力時の改行の削除,出力時の改行の付加
	-n		自動ループ
	-p		出力付き自動ループ
	-v		バージョンの表示,冗長モード

これらを使えば,例えばこんなこともできる

 % ruby -I.bak -pe 'sub "foo", "bar"' *.[ch]

これはC言語のファイルのすべての`foo'という文字列を`bar'に置
き換える.元のファイルは`.bak'という拡張子をつけて保存される.

* 簡単なプログラム

"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があっても構わない

では,実際に計算してみよう.上のプログラムに次の行を加えて
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
 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

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

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

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

しかし,シェルのように1行ずつ実行できた方が便利な時もある.
以下のプログラムを使えば,とりあえず1行ずつ実行できる.

 line = ''
 print "ruby> "
 while TRUE
   l = gets
   if l
     line = line + l 
     continue if l =~ /,\s*$/
   end
   begin
     print eval(line).inspect, "\n"
   rescue
     $! = 'exception raised' if not $!
     print "ERR: ", $!, "\n"
   end
   break if not l
   line = ''
   print "ruby> "
 end

これをeval.rbというファイルに保存して,実行してみよう.

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

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

ともかく,この小さなプログラムは結構便利だ.今後は`ruby> 'と
いうプロンプトで,このプログラムへの入力を表すことにしよう.

* 変数たち

rubyには3種類の変数と1種類の定数,それから2つ疑似変数と呼ば
れるものがある.変数と定数はその名前から区別することができる.
これはrubyの特徴の一つで,変数と定数を名前から区別することが
できるので,rubyでは明示的な変数の宣言は必要ないし,変数を見
ただけで,その種類が分かる.これはプログラムを書く時には便利
だが,タイプミスを発見しにくいという欠点が無いでもない.

まずは変数から見てみよう.rubyの3種類の変数とは,大域変数と
インスタンス変数とローカル変数である.

大域変数は`$'から始まる名前を持っていて,プログラムのどこか
らでも参照できる.初期化されていない大域変数は`nil'という特
別な値を持っている.

 ruby> $foo
 nil
 ruby> $foo = 5
 5
 ruby> $foo
 5

大域変数はプログラムのどこからでも参照,更新できるということ
は,影響範囲が非常に広いということで,濫用は危険でもある.特
に名前が重なった時には致命的な問題の元になる.あまり使わない
か,使うにしても他と重複しないような冗長な名前を付けた方が良
い(という事は上の変数名は悪い例である).

インスタンス変数はその場所で`self'で参照されるオブジェクトに
固有の変数である.同じ種類のオブジェクトでも,異なるオブジェ
クトであればインスタンス変数の値はそれぞれ異なる.オブジェク
トの外側から直接インスタンス変数の値を見たり,変えたりできな
いので,なんらかのメソッドを経由する必要がある.インスタンス
変数は`@'で始まる名前で指定される.初期化されていないインス
タンス変数の値は`nil'である.

インスタンス変数については後でオブジェクト指向のところでもう
少し説明しよう.

ローカル変数は小文字のアルファベットか,`_'で始まる名前で指
定される.他の変数と違って,ローカル変数は必ず代入によって初
期化される必要がある.最初の代入が宣言の代わりになっているか
らだ.定義されていないローカル変数の参照は引数の無いメソッド
呼出しになる.

 ruby> undefined_local_var
 ERR: undefined method `undefined_local_var' for main(Object)

ただし,メソッドの引数はもちろん代入の必要は無い.

ローカル変数の有効範囲は,

 * class ... endの間
 * module ... endの間
 * def ... endの間
 * プログラムのはじめから終りまで(上記以外)

になる.それとイテレータブロックの中ではじめて代入されたロー
カル変数はそのブロックの中だけで有効である.

 ruby> i0 = 1; print i0, "\n"; defined? i0
 1
 t
 ruby> yield{i1=5; print i0, "\n"}; defined? i1
 5
 nil

ここで使われている`defined?'は変数などが定義されているかどう
かを調べるメソッドである.`yield'は後でイテレータのところで
説明しよう.

次は定数だ.定数は大文字のアルファベットで始まる名前で指定さ
れる.定数は代入によって定義される.未初期化の定数のアクセス
や既に定義された定数への代入はエラーになる.

 ruby> FOO
 ERR: Uninitialized constant FOO 
 ruby> FOO = 5
 5
 ruby> FOO
 5
 ruby> FOO = 5
 ERR: already initialized constnant FOO

疑似変数は外見はローカル変数と同じだが,実は定数というもので
ある.名前で区別できるというルールの例外ではあるが,2つしか
ないので,間違えないだろう.

	self		現在のメソッドの実行主体
	nil		「意味が無い」値(偽を表す)

ちょっと見てみよう.

 ruby> self
 main
 ruby> nil
 nil

`main'というのはトップレベルのオブジェクトのことである.後述
するメソッドの中ではselfの値は違ったものになる.疑似変数は結
局は定数だから,`self'や`nil'には代入できない.

In This Thread

Prev Next