おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

徒然Ruby(3)ブロックとイテレータ

前回の整数の後半の内容はあまりプログラミングで使われない内容になっていました。 すみません。 今回は極めて有用なことを書きます。 ブロックとイテレーションです。

繰り返し

同じことを何回もやるときのブログラムについて述べます。例えばHello worldを3回表示したければ、

print "Hello world.\n"
print "Hello world.\n"
print "Hello world.\n"

でも良いのですが、もっと良い方法があります。 整数のメソッドにtimesというのがあります。 これはそのメソッドに付属するブロックをその整数の回数だけ繰り返すというメソッドです。

3.times do
  print "Hello world.\n"
end

doからendまでを「ブロック」といいます。 ブロックにはRubyの任意のプログラムを書けます。 timesメソッドはその整数の回数だけ繰り返すので、10回繰り返したければ10のtimesメソッドを使えば良いのです。

10.times do
  print "Hello world.\n"
end

他の言語にもブロックがあるのかどうかは知りませんが、少なくともCにはありません。 Cで同じようなことをするには関数へのポインタを使いますが、Rubyのようにスマートにしかも短く書くことはできません。

timesのように繰り返しをするメソッドでループを表現することをイテレーションといいます。

uptoメソッド

整数のメソッドで有用なもう一つはuptoです。 このメソッドには引数があります。

1.upto 5 do |i|
  print i
  print "\n"
end

整数1のuptoメソッドは1から始めて引数の5までをブロックのパラメータのiに代入してループします。 パラメータの文字はiでなくても、例えばnumberのような6文字でも構いません。 この文字は変数というものの一種です。 変数は文字列ではないのでダブルクォートで囲むことはしません。 変数については別の回で詳しく説明します。

パラメーターはそのブロックの中でのみ有効です。iには最後に5が代入されますが、ブロックが終了すると、iは消えてしまいます。ブロックの外でiを参照しても5にはなりません。

ブロックのパラメータは縦棒|で囲むことになっています。 それに対してメソッドの引数はカッコ()で囲むか、半角空白でメソッドと引数を離すのでした。 メソッドとブロックは似ていますが、本質的に違うものです。

実行すると

1
2
3
4
5

と表示されます。

uptoに似たメソッドでdowntoがあります。 これはその整数から1ずつ小さくなって、引数まで繰り返します。

10.downto(6) do |i|
  print i
  print "\n"
end

ここではメソッドdowntoの引数にカッコをつけました。 半角空白で離してカッコを省略する書き方もできます。 実行すると

10
9
8
7
6

と表示されます。

ブロックの2つの書き方

ブロックは、do, endで囲みましたが、これを波カッコにすることもできます。

1.upto(5) {|i| print i; print "\n"}

波カッコでは、ブロックが短く、1行で書ける時に使う人が多いと思います。 注意すべきは

  • 引数にはカッコをつけなければいけない。 メソッドとカッコの間に半角空白を入れない。 この理由は、Rubyがdo-endよりも{ }の方がその前の引数と強く結びつくためです(構文解析上の問題)。
  • 1行に2つの文を入れるときはセミコロンで区切る

ということです。

私は以前はdo-endを多く使っていましたが、最近は波カッコが多くなってきました。 というのは、Rubyのメソッドは優れていて、一行でブロックが収まることが多いからです。 どちらを使うかはメソッドによって9割くらい決まるように思います。 今回のtimes、upto、downtoはdo-endを使うことが多いかもしれません。

まとめ

今回はRubyの最も優れた点のひとつであるブロックを紹介しました。 ブロックは基本的にメソッドの引数の最後に現れます。 ブロック単独で現れることもあるのですが、それはかなり高度な話になります。 通常はブロックはメソッドと一緒に使われると考えて差し支えありません。

次回はメソッドをトップレベルで定義することを扱おうと思います。 この場合のメソッドは今回のブロックにちょっと似ています。