はじめに
Rubyの初学者の方から「エラーメッセージの読み方がよくわからない」という話を聞き、「Rubyのエラーメッセージを日本語化できないか」試してみた記事です。
作ったもの
Konnyaku
というgemを作りました。
gem install konnyaku
でインストールできます。
このgemではRubyのエラーメッセージを日本語に変換して出力することができます。 例えば、以下のようなコードがあったとします
puts Hoge # => 未定義の定数 Hogeがputsに渡されている
このコードを実行すると以下のようなエラーが表示されます
uninitialized constant Hoge (NameError)
実行結果: [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
定義されていない定数Hoge
を参照しているのでエラーになっているわけですね
慣れていれば問題はないのですが、初学者の方には英語表記であるため読みにくさを感じるようです
そこで、Konnyaku
出番です!
先ほどのコードにrequire "konnyaku"
を追加すると以下のようにエラーメッセージが日本語で表示されます
require "konnyaku" p Hoge #=> 例外:NameError が発生しました #=> ソースコード: bug.rb の 3 行目にエラーの原因があります #=> 定義されていない定数 Hoge があります
Konnyaku
を使うことで、こんな感じでエラーメッセージを日本語として表示してくれます
やったこと
TracePoint
を使って、例外が発生したタイミングでエラーメッセージを日本語に強制的に書き換えることをしています。
class Konnyaku class << Konnyaku def run tp = TracePoint.new(:raise) do |tp| lineno = tp.lineno path = tp.path msg = tp.raised_exception.message puts "例外:#{tp.raised_exception.class} が発生しました" puts "ソースコード: #{path} の #{lineno.to_s} 行目にエラーの原因があります" msg = translate(msg) puts msg end tp.enable end end end
エラーメッセージなどの変換はKonnyaku.translate
で以下のように無理やり置換しています(このへんもう少しきれいにしたい……)
class Konnyaku class << Konnyaku def translate(msg) case msg when /uninitialized constant/ return msg.gsub(/#{$&}/, "定義されていない定数") + " があります" when /undefined local variable or method/ return msg.gsub(/#{$&}/, "定義されていない変数またはメソッド").gsub(/ for /, " が ").sub(/`|'/, "").gsub(/for/, "") + " にあります" when /undefined method/ return msg.gsub(/#{$&}/, "定義されていないメソッド").gsub(/ for /, " が ").gsub(/`|'/, "") + " にあります" when /uninitialized class variable/ return msg.gsub(/#{$&}/, "初期化されていないクラス変数").gsub(/ for.+$/, "").gsub(/ in /, " が ") + " クラスにあります" end end end end
今後
とりあえず、対応していないエラーメッセージとかまだまだあるので追加していこうかと思います。 あと、テスト書けてないのでその辺も進めていきたい……