Rubyで使えるメソッドの中には、引数の他に、do~endまたは{}で囲まれたブロック構文を利用するメソッドが少なくありません。そして、ブロック構文を使うメソッドとしてよく使われるのがeachメソッドですが、使ううえで注意してほしい点もあります。
そこで今回は、do~endまたは{}で囲まれたブロック構文の使い方を、eachメソッドなどの例を使って解り易く解説します。
ブロック構文の基本
Rubyに組み込まれたメソッドの中には、ブロック構文を使って処理や条件を指定可能なメソッドがあります。そして、ブロック構文は、doで始まり、endまでが範囲です。また、省略して{}で囲む書き方も可能です。
まずは、ブロック構文の基本について解説します。
Rubyにおけるメソッドの呼び出し方法
Rubyでメソッドを呼び出す場合、次の2種類の方法があり、どちらの方法が使われるかは、メソッドによります。
・メソッドと引数で呼び出す
メソッド名のみ、または、メソッドに続けて括弧内に引数を指定する方法です。引数は、値や変数の他、式も記述できます。
メソッド
メソッド( 式… )
・ブロック付きメソッドで呼び出す
do~endまたは{}で囲った制御構造を付けてメソッドを呼び出す方法です。eachメソッドなど、繰り返し処理の内容を記述する場合などで使われます。そして、do~end、または、{}内の制御構造がブロック構文です。
メソッド do 制御構造 end
メソッド { 制御構造 }
ブロック構文の使い分け
先ほど紹介したように、ブロック構文には、do~endで囲む方法と、{}で囲む方法とがあります。厳密に言えば、この2つの方法は、結合の強さが違い、{}が優先されますが、実際のRubyのプログラミングでそれを意識するケースはほとんどありません。
むしろ、どちらが見やすいかを意識してプログラムで使うことの方が多いでしょう。そして、{}を使うと見やすいケースは、次のとおりです。
・ブロック構文付きのメソッドを1行で書く場合
・ブロック構文付きのメソッドの戻り値を利用する場合
・ブロック構文付きのメソッドを、さらに別のメソッドで利用する場合
上記以外のケースでは、do~endで囲む方法を検討してください。
ブロック構文を使うメソッドは作れる
Rubyでは、独自のクラスを作成し、その中にメソッドを作り、プログラムで活用するケースがよくあります。そして、その独自のメソッドで、ブロック構文が使える設定も可能です。
なお、ブロック構文を使うメソッドを定義する場合に使用するメソッドが、yieldです。ここでは、yieldの解説はしませんが、興味のある方は使い方を調べてみてください。
do~endの基本
先ほど説明したように、Rubyで使われるブロック構文は、doとendで囲う書き方と、{}で囲う書き方が可能です。次から、ブロック構文の書き方を、do~endで記述した例を用いて解説します。
配列のeachメソッドのブロック構文の書き方
Rubyのプログラムでよく使われて、ブロック構文を使うメソッドとして挙げられるのがeachメソッドです。eachメソッドは、配列に含まれる要素を順にブロック構文内の処理を実行します。そして、要素を処理する際に使用する変数を、||に挟んで記述します。
配列におけるeachメソッドのブロック構文
配列.each do | 変数名 |
処理
end
なお、doとendの間に記述する処理として、複数のコマンドを記述できます。
配列におけるeachメソッドのブロック構文の例
arr = [ 1, 2, 3, 4, 5 ] sum = 0 arr.each do |item| sum = sum + item end p sum
ハッシュのeachメソッドのブロック構文の書き方
先ほど、配列のeachメソッドを例に、ブロック構文の中で1つの変数を||で囲った例を紹介しましたが、||内には複数の変数を設定できます。例えば、ハッシュに対してeachメソッドを利用した場合は、||内にキーと値の2つの変数を設定します。
ハッシュにおけるeachメソッドのブロック構文
ハッシュ.each do | キー, 値 |
処理
end
ハッシュにおけるeachメソッドのブロック構文の例
hash = { "No."=>1, "Name"=>"Suzuki", "Section"=>"Sales" ] strs = "" arr.each do |key, value| if key == "Name" then strs = value end end p strs
selectメソッドのブロック構文の書き方
先ほど紹介したeachメソッドでは、配列や要素を使ったプログラムをブロック構文の中に書けましたが、ブロック構文の使い方は、それだけではありません。
配列のselectメソッドは、配列の要素を評価し、該当する要素のみ格納した配列を返すメソッドです。そして、selectメソッドでは、ブロック構文の中で、評価するための条件を記述します。
arr = [1, 2, 3, 4, 5] out = arr.select do |x| do x > 3 end p out # [4, 5]が表示される
この例では、配列arrに対して、selelctメソッドを実行しており、do~endで囲まれたブロック構文の中に条件の「x > 3」を記述しています。
また、Rubyには、selectメソッドのようにブロック構文で条件や式を指定するメソッドが、他にも幾つもあります。配列やハッシュのメソッドを使用する際に、注視してください。
do~endブロック構文内の変数の扱い
先ほども説明したように、Rubyでは、do~end内または{}内に処理を記述するブロック構文を利用でき、その中では変数を用いたプログラムを記述できます。
そして、先ほど説明したように、||内で宣言した変数の他、ブロック構文の外部で宣言した変数、およびブロック構文の内部で宣言した変数が利用可能です。ただし、ブロック構文の内部で宣言した変数は、ブロック構文の外では参照できません。
次に、例を用いて解説します。
ブロック構文の外で宣言した変数は中で使える
先ほど紹介した配列におけるeachメソッドのブロック構文の例では、ブロック構文の外で宣言した変数sumを利用していました。
arr = [ 1, 2, 3, 4, 5 ] sum = 0 # ブロック構文の外で宣言した変数 arr.each do |item| sum = sum + item # ブロック構文の外で宣言した変数sumは、ブロック構文の中でも使える end p sum
この例では、ブロック構文の外で変数sumを宣言し、ブロック構文の中で、「sum = sum + item」として利用しています。さらに、この変数は、eachメソッドの次の処理でも利用可能です。
ブロック構文の中で宣言した変数は外で使えない
ブロック構文の中で変数を作って利用できますが、その変数をブロック構文の外では利用できません。例えば、次の例のようにブロック構文の内部で作った変数は、ブロック構文の外から参照しようとするとエラーが発生します。先ほどのハッシュにおけるeachメソッドのブロック構文の例を利用して解説します。
エラーになるハッシュにeachメソッドを使った例
hash = { "No."=>1, "Name"=>"Suzuki", "Section"=>"Sales" ] #strs = "" arr.each do |key, value| if key == "Name" then strs = value end end p strs
上記の例は、先ほど紹介したハッシュにおけるeachメソッドのブロック構文の例から、eachメソッドの直前の「strs = “”」をコメントで削除した例です。
このRubyのプログラムを実行すると、変数strsがブロック構文の中で作られたことになり、最後の「p strs」で、変数strsが定義されていないというエラーが発生します。
まとめ
これまで説明したように、do~end、または、{}で囲まれたブロック構文は、eachメソッドなどで使われる便利な構文です。そして、まるでメソッドのように変数を利用できます。また、メソッドによっては条件のみ記述するケースもあるなど、Rubyにはブロック構文を使うメソッドが幾つもあります。
Rubyでプリグラムを作る際には必須の機能なので、ぜひ、使い方をマスターしてください。