もう少しエラー処理を頑張ってみる
第 30 回 Ruby/Rails 勉強会の演習問題の RPN 電卓。
他の人の解答を見ると、エラー処理を頑張ってる人がいたので、自分も頑張ってみる。
今回の演習では、まずスタックを作って、そのスタックを使って RPN を作る。
空のスタックから pop しようとすると Stack::EmptyStackError 例外が出る仕様。
なので、前回の RPN 電卓 その弍 に例外ハンドラを書いてみる。
require 'stack' def rpn(exp) num = Stack.new exp.each do |i| if /\D/ =~ i num.push(num.pop.__send__(i, num.pop)) else num.push i.to_i end end raise SyntaxError if num.size > 1 # 数が残ってるがな num.pop end if $0 == __FILE__ begin puts "#{ARGV.join(' ')} = #{rpn(ARGV)}" rescue ZeroDivisionError STDERR.puts "zero divide: #{ARGV.join(' ')}" rescue NoMethodError, ArgumentError STDERR.puts "invalid operator: #{ARGV.join(' ')}" rescue Stack::EmptyStackError STDERR.puts "too many operator: #{ARGV.join(' ')}" rescue SyntaxError STDERR.puts "too few operator: #{ARGV.join(' ')}" end end
例外を使うと、エラー処理を 1 ヶ所にまとめられる (ことが多い) のでコードがスッキリする。
$ ./rpn.rb 4 3 2 \* / 4 3 2 * / = 1 $ ./rpn.rb 4 7 % # +-*/ 以外も使えてお得 4 7 % = 3 $ ./rpn.rb 4 7 to_f / # 二項演算子でないと呼べない invalid operator: 4 7 to_f / $ ./rpn.rb 4 7 @ # @ ってどんな演算だよ invalid operator: 4 7 @ $ ./rpn.rb 0 3 / # 0 で割れない zero divide: 0 3 / $ ./rpn.rb 4 7 % + # 演算子が多い too many operator: 4 7 % + $ ./rpn.rb 4 7 % 8 # 数値が多い too few operator: 4 7 % 8