Ruby超入門 2周目 CHAPTER11-1 例外処理 まで

f:id:kkouji0224:20191027224451p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

マジで寝ても寝ても体が思い。まぶたが重い。頭も重い。

そんな感じ。koujiです。こんばんは。

 

今日はCHAPTER10の途中まで振り返っていこうと思いますっ!

 

例外処理だぜ!

 

puts "残高を入力してくれ!"
bank_balances = gets.to_i
puts "次の給料日までの日数を入力してくれ!"
days = gets.to_i

oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"

 

上のプログラムはgetsメソッドで入力を取り込んで.to_iメソッドで文字列を整数に変換して、単純に金額/日数で一日あたりの金額をだしてるんだけど、ここで日数で0を入力するとエラーが出るんだよね。

 

こんな感じ。

 

f:id:kkouji0224:20191109231955p:plain

 

エラーでZeroDivisionErrorってのがでてるね。これはonedayのところでbank_balances / daysで5000/0の0で割ろうとするときに出てる例外エラー。で、エラーが発生してるので次の行のputsは実行されないって感じだね。で、このZeroDivisionErrorは例外クラス

 

rescueで例外を処理する

 

puts "残高を入力してくれ!"
bank_balances = gets.to_i
puts "次の給料日までの日数を入力してくれ!"
days = gets.to_i

begin
oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

 

beginからrescueの間に例外が発生しそうな処理を書くんだね。で、rescueからendの間に例外が発生した時の処理を書く感じ。で、今回はZeroDivisionError例外を処理するので、resucue ZeroDivisionErrorって書くようにしてると。これで給料日までの日数を0で入力すると結果はこんな感じ。

 

f:id:kkouji0224:20191109233414p:plain

 

ヒャッハー!!5万貯金できるぜ!!

 

rescueをメソッド内で使う場合

 

def oneday(bank_balances, days)
oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

oneday(50000, 0)
oneday(50000, 10)

 

メソッドの中で使う場合はbeginとendを省略して書いてもOK。メソッドのはじめからresucueまでのところで例外が発生したら、rescue ZeroDivisionErrorで受け取れちゃう!

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

 

ちなみにブロックないでもbeginとendを省略してこんな感じで書けちゃうね!

 

例外の情報を取得できるよ!

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError => e
puts "※※※例外発生※※※"
puts "例外クラス: #{e.class}"
puts "例外メッセージ: #{e.message}"
end

 

rescue ZeroDivisionError => e このeは変数でこの場合はZeroDivisionErrorオブジェクトを代入してるね。で、putsのところでオブジェクト名.classとか.messageでクラスとメッセージを取得してるね。.classとか.messageは例外クラスで使えるメソッド!

 

ちなみにrescueは指定したクラスだけじゃなくて、サブクラスも補足できちゃうんだね。例えばZeroDivisionErrorの場合は親クラスがStandardErrorなので…

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue StandardError => e
puts "※※※例外発生※※※"
puts "例外クラス: #{e.class}"
puts "例外メッセージ: #{e.message}"
end

 

こんな感じで書いてあげてもZerodivisionErrorを補足できるんだね。便利だ…

さらにちなみになんだけど、rescue => e は rescue StandardError => eと同じ。

 

raiseメソッドで例外を発生させる

 

ef rich(cash)
if cash < 0
raise "借金が#{cash}円です!"
elsif cash < 1000000
"貧困です"
elsif cash < 10000000
"小金持ちです"
else
end
end

cash = ARGV.first.to_i
rich = rich(cash)
puts "#{cash}円は#{rich}"

 

上の場合はcashがマイナスだった場合にraiseメソッドで例外を発生させてるよ。rescue使ってないので、例外が補足されないのでputsは実行されないんだね。raiseメソッドで例外メッセージのみを指定した場合はRuntimeErrorになるよっ!

 

ensureで例外があってもなくても処理を実行する

 

def rich(cash)
if cash < 0
raise "借金が#{cash}円です!"
elsif cash < 1000000
"貧困です"
elsif cash < 10000000
"小金持ちです"
else
end
end

begin
cash = ARGV.first.to_i
rich = rich(cash)
puts "#{cash}円は#{rich}"
rescue => e
puts "例外発生: #{e.message}"
ensure
puts "お金はいくらあっても足りないぜ!"
end

 

beginとrescueの間に例外が発生しそうな処理をかいてensureのところに例外があってもなくても実行する処理を書く。実行するとこんな感じ。

 

f:id:kkouji0224:20191110004418p:plain

 

見ての通りなんだけど、-5で例外を発生させても「お金はいくらあっても足りないぜ!」だし、例外にならない数にしても「お金はいくらあっても足りないぜ!」が表示されてるね。ensureは書いておくと発生の有無に関係なく実行してくれる頼もしいやつだぜ。

 

実は例外処理って便利そうだけど退屈そうだなぁ…って始める前は思ってたんだけど、2周目やってみるとこれはこれでなかなか便利というか面白いんじゃないかなって気になってきた。明日が休みだから楽しく感じるのか… いやそんなことない。1周目の時よりも面白く感じる。これは確かだ!!てか、便利だよね。

 

ってことで例外処理を振り返ってみましたー!

 

こうやって振り返ってると体のダルさを忘れられるから不思議だぜ…

 

ってことで今日はこの辺で!

 

アディオス!