繰り返しとブロック
ブロック
Rubyではブロックと呼ばれるコードのかたまりを、
メソッドを呼び出すときに渡すことができる。
これは繰り返しの処理の時によく使われる。
10.times do |i|
print i, " , "
end
0から9までのし数字が表示される処理
10.timesの10は「10」という値を持つ数値オブジェクト
timesは数値オブジェクトのtimesメソッドの呼び出し。
ブロックは、doからendまでのひとかたまりで、
ブロックを渡されたtimesメソッドは数値の回数分(10)だけブロックを繰り返します。
また、ブロックは「|」と「|」で囲んでブロックパラメータを指定できる。
上記例では「i」がブロックパラメータ。※do〜endの処理を持っている
この処理ではtimesメソッドはiの数値を0から9まで1ずつ増やしながら、
繰り返しブロックを実行します。
その結果、print i, “,”」でiの値が10回表示されます。
またブロックはdoとendの代わりに、{と}で囲むことができる。
10.times { |i| print i,","}
メソッドに引数とブロックを両方渡すときは、「メソッド名(引数)do end」と記述する。
下記例のサンプルコード
※uptoメソッドは指定された数まで値を増やしながら繰り返す処理。
※2,3,4,5,6,が表示される。
2.upto(6) do |i|
print i, ","
end
※downtoメソッドやstepメソッドなどもあるよ。
eachメソッド
配列(Array)にはブロックを使った便利なメソッドがありその代表がeachメソッド。
eachメソッドはブロックパラメータ(次の例ではitem)に配列の要素を入れながら、配列の要素数だけブロックを繰り返し実行します。配列の要素を順番に処理するためにはeachメソッドを使うのが普通です。
arr = ["apple","orange","grape"]
arr.each do |item|
print item + ","
end
配列の要素とともに要素の番号もあつかいたいときは、each_with_indexメソッドをつかう。
ブロックパラメータには|item,i|がはいる。
arr = ["apple","orang","grape"]
arr.each_with_index do |item, i|
print "#{i}.#{item}"
print ", " if i < arr.length - 1
end
whileとfor
Rubyでも他言語にあるようなwhileやforでのループをつかえる。
ただし、Rubyプログラマはブロックを受け取るメソッドを使うことが多いので、実際にはあまり使われません。
i = 0
while i < arr.length
puts arr[i]
i += 1
end
#と
for item in arr
puts item
end
ブロックの受け取りとかに関しては、
ブロックの利用のところ読みなおす。
http://www.yukun.info/blog/2008/01/ruby-block.html
繰り返し以外のブロック
ブロックを受け取るメソッドは繰り返し以外にもある。
Fileクラスのopenメソッドは、
「ファイルを開く→ブロックパラメータにFileオブジェクトを渡してブロックのコードを実行
→ファイルを閉じる」という処理を行う。
※ファイルを閉じるというコードを書かなくても良い。
例では、ファイルを作ってその中にこんにちはと書き込む処理。
File.open("output.txt", "w", encoding: "utf-8") do |file|
file.puts "こんにちは"
end
openメソッドの第二引数の”w”は書き込み用にファイルを開くことを示します。
読み込み用なら”r”とするか省略します。
第三引数「encoding: “utf-8″」はハッシュでファイルの文字コードを指定している。
Railsでは繰り返し以外の目的でブロックを受け取るメソッドがある。
代表的なのは「form_for」メソッド
def stopwatch(time)
start = Time.now.to_f
time.times { |i| yield i }
Time.now.to_f - start
end
secs = stopwatch(10000) do |i|
Math.sqrt(i)
end
puts "#{secs}秒かかりました"
この部分よくわからんから聞きたい?
→今は気にしない。これが理解できたら一人前。
例外処理
プログラムの実行中に何らかのエラー(例外)が発生した時に
そのエラーを捕まえて後始末を行う仕組み。
Rubyでは「begin~end」で記述する。
例外が発生すると、プログラムの実行を中断し、すぐにrescue以下載せつが実行されます。rescue節では、エラーメッセージなどを記述しておく。
rescue節の下にはelse節をおいて、例外が発生しなかった場合の処理を
記述してくことも可能!
begin
例外が発生する可能性のあるプログラム
rescue
例外の発生後に処理するプログラム
else
例外が発生しなかった場合のプログラム
end
メソッドの中で、beginなしでrescue節やelse節をおいて例外処理を行うこともできる。
def メソッド名(引数)
例外の発生する可能性のあるプログラム
rescue
例外の発生後に実行するプログラム
else
例外が発生しなかった場合のプログラム
end
ファイルからデータを一行読み込んで表示するものですが、
存在しないファイルを指定しているので実行されない。
その時の例外処理
begin
File.open("some.txt", encoding: "utf-8") do |f|
print f.gets
end
rescue
warn "エラー発生"
end
例外が発生した時は例外を表すオブジェクトを調べ、
例外の種類やメッセージを取り出す事ができます。
例外オブジェクトを調べるには、rescue節を「rescue => 変数」のように記述する。
変数eに例外オブジェクトを取り出そ、クラス名とエラーメッセージを取り出す。
begin
File.open("some.txt", encoding: "utf-8") do |f|
print f.gets
end
rescue => e
warn "#{e.class}", "#{e.message}"
end
例外を発生させるには、
プログラム野中でエラー処理のために自分で例外を発生させるには、raiseメソッドを使います。raiseメソッドに文字列を指定すると、RuntimeErrorクラスによる例外が発生します。
begin
raise "ファイルがない" unless File.exist?("some.txt")
rescue => e
warn e.message
end
今日はここまでにしとくか。
本記事は下記本の勉強記事です。初学者にとても良い本です。