■ Ruby のお決まり: 文法 1

Ruby の基本的な決まりと、Ruby をファイルに保存して実行するまでの方法です。

■ 実行サンプルについて

Ruby には irb (Interactive RuBy) という対話的に利用できる Ruby が付属しています。 インストールすると irb というコマンド名で実行可能になっています。 これを使用すると、ちょっとした確認のときにとても便利です。 確認を行う際にこの irb を使います。

例:
$ irb
irb(main):001:0> print "test"
testnil
irb(main):002:0> puts "test"
test
nil
irb(main):003:0> p "test"
"test"
nil
irb(main):004:0> 
print」は、メッセージを出力します。 明示的に改行を指定しない場合は、改行は出力されません。 このため、メッセージ「test」と irb が出力している「nil」が連続しています。 「puts」は、メッセージを表示するときに改行を出力します。 例では、「nil」の出力が次の行になっていることで、print との違いがわかると思います。 「p」は、とっても便利なオブジェクト確認用のコマンド(メソッド)です。 オブジェクトの内容を表示しますので、活用しましょう。

対話的な Ruby の実行は、作業されている OS などにより、うまく動作しない場合もあります。 このようなときは対話的な使い方ではなく、スクリプトを作成して、実行してみてください。 スクリプト言語は、エディタなどでスクリプトを作成してすぐに実行できるのでとっても手軽ですから。 ファイルに書きためれば、あとからの利用も可能ですし。

■ 変数

数値や文字列などの「オブジェクト」の入れものが「変数」になります。 オブジェクトという言い方をすると分かりにくいかもしれませんが、とりあえずは入れものと考えてください。 つまり、変数は入れもので、中身はオブジェクトと考えてください。

例:
$ irb
irb(main):001:0> number = 123
123
irb(main):002:0> string = "string"
"string"
irb(main):003:0> p number
123
nil
irb(main):004:0> p string
"string"
nil
irb(main):005:0> 
number」に数値 123 を入れています。 Ruby では数値もオブジェクトです。 次に「string」に文字列 string を入れています。 もちろん文字列もオブジェクトです。 Ruby では、文字列を「"」または「'」で囲みます。

もう一つの考え方として、変数はオブジェクトへの「ラベル」と考える方法もあります。 「オブジェクトを変数に代入する」という動作は、「オブジェクトにラベルを張り付ける」という感じです。 上記の例では、オブジェクトの数値「123」にラベルとして number という名前をつけたと考えてください。

大切なお約束(お決まり)があります。 これは、変数は使用する前に必ず初期化することが必要です。 参照する前に初期化を済ませるようにしてください。 初期化を行わないとエラー(例外が発生)になってしまいます。 スクリプト言語では、初期化しない場合にデフォルトの値を持つものが多いようですが、Ruby は明確に初期化が必要です。 これは、間違いの起きにくいプログラミングを実施するためにもとてもいいことです。

$ irb
irb(main):001:0> p a
NameError: undefined local variable or method `a' for #<Object:0x2ac2cb14>
        from (irb):1
irb(main):002:0> 
変数を参照する前には、初期化を実施しましょう。

次の例は、代表的な変数の初期化です。

数値number = 0
文字列string = ''
配列array = []
ハッシュ(連想配列)hash = {}

● 種類

変数には次のような種類があります。

種類記述方法サンプル
ローカル小文字ではじまるvar, num, str
グローバル$ ではじまる$var, $num, $str
インスタンス@ ではじまる@var, @num, @str
クラス@@ ではじまる@@var, @@num, @@str
定数大文字ではじまるVAR, NUM, STR

ローカル変数

有効範囲に決まりがある変数です。 値を代入して定義した場所により有効範囲のタイプがあります。 変数が有効な範囲からメソッド内のローカル変数やブロック内のローカル変数があります。 Ruby では、ローカル変数が基本になっています。

グローバル変数

グローバル変数は、どこからでも変更も参照もできる変数になります。

どこからでも使えるということは便利に思えるかもしれません。 ですがが、プログラミングという世界の話題としては、「よくない」とされています。 すこしでもプログラム(スクリプト)が大きくなってくると、どこでその値を変更しているのかわかりにくくなるためです。 グローバル変数を使うときには、注意しましょう。

インスタンス変数

生成されたオブジェクト(インスタンス)内で有効な変数になります。 オブジェクトの情報(状態)の入れものです。

クラス変数

同じクラス内で有効な変数です。

この変数もグローバル変数と同じ問題がありますので、使う場合には注意してください。

定数

直接「数字」などが現れた場合、スクリプトないではなにを意味するかわかりにくくなります。 このため、固定値などを示すための定数があります。 クラス内で定義することで、クラス定数が定義可能です。

● 有効範囲(スコープ)

Ruby の手軽さの一つがこの変数のスコープ(有効範囲)です。 Ruby では、普通に小文字ではじまる変数名を使うとローカル変数となります。 ローカル変数の有効範囲は、変数が定義されているメソッド(関数のようなものです)内になります。 または、ブロック(イテレータともいう)内(繰り返し処理を「{|var| ...}」で記述した場合)になります。

黙って使うとローカル変数ということは、スクリプトをつくる際にあやまって(気が付かずに)他の変数を変更してしまうようなことが起きにくくなります。 すべての変数がグローバル変数の場合、ちょっと大きなスクリプトを記述するときには、とても注意が必要になります。 それは、一時的に使用する変数が他のところで使われていると、値を変更してしまう可能性がでてくるからです。 ローカル変数が基本になっている場合、そういう細かな部分は気にせずに一時的な変数を使用できます。 もちろん、ローカル変数の有効範囲内では注意が必要ですけど、対象はそれほど大きくないのでスクリプトのつくり手としては助かります。 あと、ローカル変数を使うのに特別な宣言は必要ありません(宣言が必要だとめんどうですよね)。 基本的に使用される変数はローカル変数なんです。 便利でしょ。

● 配列

配列は、要素(オブジェクト)を複数まとめて入れる入れものです。

$ irb
irb(main):001:0> arr = []
[]
irb(main):002:0> arr[0] = 1
1
irb(main):003:0> arr[1] = 2
2
irb(main):004:0> p arr
[1, 2]
nil
irb(main):005:0> arr = [1, 2, 3]
[1, 2, 3]
irb(main):006:0> p arr
[1, 2, 3]
nil
irb(main):007:0> p arr[1]
2
nil
irb(main):008:0> 
いろいろなオブジェクトを入れることができるので数値だけではなく、文字列でも配列でも入れることが可能です。 配列に配列を入れるのが簡単にできちゃいます。
$ irb
irb(main):001:0> arr = [1, 2, 3]
[1, 2, 3]
irb(main):002:0> arr[3] = [4, 5, 6]
[4, 5, 6]
irb(main):003:0> p arr
[1, 2, 3, [4, 5, 6]]
nil
irb(main):004:0> 

● ハッシュ(連想配列)

ハッシュは、要素(オブジェクト)を「キーワード」で管理できる入れものです。 「キーワードに一致した要素」という形で使用できます。 「キーワード」にはもちろん文字列(オブジェクト)も使用可能です。 これは便利ですよ。

$ irb
irb(main):001:0> h = {}
{}
irb(main):002:0> h['name'] = "WATANABE Tetsuya"
"WATANABE Tetsuya"
irb(main):003:0> h['age'] = 39
39
irb(main):004:0> p h
{"name"=>"WATANABE Tetsuya", "age"=>39}
nil
irb(main):005:0> p h['name']
"WATANABE Tetsuya"
nil
irb(main):006:0> 

● 変数 $_

変数「$_」は、省略された場合のデフォルト変数として使われることがあります。 Ruby の場合は、メソッド/関数形式の場合、次の処理で利用されています。 また、文字列の比較などのデフォルトの対象になります。 なんでもかんでも「$_」をデフォルト変数/引数として使用するというわけではありません。

gets
readline
print
split
scan
chop
chop!
chomp
chomp!
gsub
gsub!
sub
sub!
また、「$_」はローカル変数です。 このためいつのまにか値が変わってしまっているというような問題も発生しません。 手軽な処理を記述する「手助け変数」となっています。

sub, gsub については、ちょっと注意が必要です。 オブジェクトを省略した形の sub, gsub は、対象を $_ に格納されているオブジェクトになります。 このとき、sub!, gsub! でなくとも、結果として $_ が示している内容が「入れ替る」ことが発生します。 動作としては次のようになります。 sub, gsub では、最初に $_ が示しているオブジェクトのコピーを作成します(dup, clone)。 このコピーを対象に sub, gsub が実施されます。 実施後 $_ が示しているオブジェクトは、コピーが作成され修正されたオブジェクトになります。

while gets
  gsub(/ruby/, 'Ruby')
  print
end
というスクリプトは、ちゃんと動作します。 gsub で直接 $_ を変更しているようにみえなくても、結果として $_ が変更されているということです。 この動作は、chop, chomp も同様です。

便利な $_ ですが、Ruby world のみなさんの間では、「なるべく使わないようにしよう」ということになっているようです。 変数名を明示しないため、スクリプトに気がつきにくいミスが入り込むことが考えられるからのようです。

■ メソッド/関数

処理をまとめて実施したい場合には、扱いやすい単位で別けて作成するととても楽になります。 オブジェクト指向では、オブジェクトに対する処理をメソッドとして記述します。 最初は単純に一般的な言語での関数のように考えてください。 扱うデータに対してよく使う処理をまとめておくということが可能になります。 書き方としては次のようになります。

def メソッド名
  ...
end
ローカル変数は、この「def ... end」の範囲内だけ有効になります。

● メソッド/関数の引数でのデフォルトの値

メソッドには、引数を指定できます。 このとき、手軽にデフォルトの値を設定できます。

def sample(val = 'default')
  ...
end
という感じです。 引数がしていされると、その引数が変数に代入されます。 引数が省略されると、デフォルトとして設定されている値(オブジェクト)が使用されます。

exit の意味

Ruby のスクリプトを実行します。 このとき、終了を示す意味で、exit をスクリプトの中で実行します。 そうすると終了ステータスとして 0 となります。 0 は正常終了の意味です。

処理によっては、正常ではない終わり方をします。 このときは、0 以外の値を exit の引数として渡します。 そうするとコマンドの終了ステータスとなります。

終了ステータスは重要です。 正常に終了したか、そうでないかの判断を外部にしらせるためにも必ず利用してください。 正常終了時の exit は、明示しなくても Ruby スクリプトが正常終了すれば終了ステータスは 0 になります。 エラーのときは必ず指定しましょう。

UNIX 系の grep というコマンドは、この終了ステータスをうまく利用しています。

ステータス意味
0正常終了
1みつからない場合
2エラーの場合
この値を判断することで、検索がうまくいったか、みつからなかったか、エラーなのかの判断がプログラム的に可能になります。

Ruby の場合は、明確的に exit を記述しなくとも、終了ステータスは 0 になります。 また、例外が発生すると 1 になります。

■ エラー/例外処理

Ruby は、例外処理を持っています。 Ruby では、エラー処理を例外として扱っています。 基本的にエラーが起きると例外が発生します。 そして、例外によってメッセージを表示して停止します。 このため、「エラーの場合はエラーメッセージを表示して停止」のような記述を書く必要はありません。 これはお手軽スクリプトを書くときにとても楽になります。

一般に? スクリプトやプログラムを書くことになれていない人の場合、エラー処理というものをなかなかうまく書けません。 自分の手元ではうまく動く場合がほとんどで、どういうときにエラーが起きて、それをどうすればいいかというのが分からないためです。 Ruby の場合には、特別な記述なしに適当に処理してくれるのがうれしいところです。 もし、エラーが起きたときの対応が必要な場合には、「例外」を受け取るような処理を記述すればいいのです。 ですから、最初のうちは特にエラーを気にした記述は必要ありません。 これはとっても楽ですね。

クラス定義内でのメソッドや、処理をまとめただけの関数(メソッド)の場合でも同様に楽ができます。 もし、エラー処理が必要な場合には、メソッドを呼びだしているところで、例外をハンドリングすればいいのです。

C や Perl などの場合、エラー処理を記述しないとエラーを確認できません。 明確に記述していないとエラーを確認できないため、エラー処理を記述しないと次のようなことになります。

データが読めないということだけならいいのですが、データを読めるつもりで記述され部分でデータが読めないために次のようなことが起きます。 一つが異常終了してしまうこと、そして、エラーだと気付かずにそのまま処理が進んで意味のない結果を出力することもあります。 また、実際エラーがどこで起きたか? 何が原因でエラーになったかということが分かりにくくなり、問題の特定に時間がかかったりします。 「手軽に処理」するつもりがこれでは問題の発見がなかなかできなくて... 「手軽に処理」するつもりがエラー処理のためにとっても大変になったりして... Ruby は、手軽に目的の処理を記述すれば OK です。

ファイルをオープンする場合の例を書きます。

$ irb
irb(main):001:0> file = File.open('/etc/hosts')
#<File:0x2ac5106c>
irb(main):002:0> l = file.gets
"127.0.0.1\tlocalhost.localdomain localhost\n"
irb(main):003:0> file = File.open('12345')
Errno::ENOENT: No such file or directory - "12345"
        from (irb):3:in `open'
        from (irb):3
irb(main):004:0> 
/etc/hosts」というファイルは存在しているので問題なく処理できます。 「12345」というファイルは存在しません。 エラー処理を特に行っていませんがちゃんとエラーになっています。

ちなみにシステムが日本語の環境ではこんな感じにエラーメッセージがでます。 Ruby が日本語でエラーメッセージをだすというのではなく、システムがエラーメッセージを日本語でだしているということです。

irb(main):001:0> File.open('12345')
Errno::ENOENT: そのようなファイルやディレクトリはありません - "12345"
        from (irb):1:in `open'
        from (irb):1
irb(main):002:0> 

■ スクリプトをファイルに保存して実行

一連の手順をスクリプトに書くときに、ファイルに書き込んでそれを実行します。 Ruby では、ファイルの拡張子を「.rb」にします。 また、UNIX 系のシステムで実行する場合にはファイルの先頭に「#! /usr/local/bin/ruby」と書くことで、そのファイル内のスクリプトを ruby コマンドが実行します。 このとき、ruby コマンドが /usr/local/bin/ruby にインストールされているものとしています。 もし違うところにインストールされている場合には、その ruby のパスを指定するか、シンボリックリンクを利用するといいでしょう。 または、「#! /usr/bin/env ruby」と指定する方法もあります。 この場合は、ruby がインストールされているディレクトリが特定できない場合にコマンド env の機能を利用して ruby を実行します。 次のサンプルはお約束の「hello world」です。

#! /usr/local/bin/ruby
# /home/tetsu/src/ruby/intro/hello.rb
# Created: May 17,1998 Sunday 21:37:09
# Author: tetsu(WATANABE Tetsuya)
# $Id$
# usage:

print "hello world\n"

exit        # 省略可能です
コメントは「#」ではじまり、行の終りまでです。 ファイルにスクリプトを記述する場合には、記録を残す意味でコメントも活用しましょう。

このファイルをエディタで作成します。 作成したファイルの実行方法はいくつかあります。 ファイルができ上がったら次のようにコマンド ruby の引数として実行する方法です。

$ ruby hello.rb
hello world
また、ファイルの先頭におまじないの「#! /usr/local/bin/ruby」がありますのでスクリプトを直接実行できるようにパーミッションを変更します。
$ chmod +x hello.rb
$ ./hello.rb
hello world
$ ls -l hello.rb
-rwxr-xr-x   1 tetsu    staff         179 May 17 21:38 hello.rb
これで、スクリプトを作成して自分のコマンドをつくることが可能になります。 いつでも使いたい場合には、環境変数 PATH が示すディレクトリに作成したコマンドをインストールします。 個人用のものでしたら、~/bin というディレクトリを作成して、そこに入れるのがいいでしょう。 もちろん、環境変数 PATH にも ~/bin を追加することが必要になります。

さて、簡単ですが、Ruby のスクリプトを実行するための最低限の部分を説明しました。 Ruby には便利なリファレンスマニュアルがあります。 これらを参考にして、いろいろなスクリプトを実行して修正して試してみてください。 実行して修正して試した数だけ、Ruby がどんどん便利になりますよ!


渡辺哲也(WATANABE Tetsuya): Tetsuya.WATANABE atmark nifty.com