はじめに
プログラムをデバッグするときはデバッガーを使ったり二分探索でコメントアウトしてみたり、ログを出してみたりすると思います。
私はログを出してデバッグするのをよくやるのですが、ただ単に
p "value => #{value}"
とか
p value
とかでデバッグしようとしたとき、小さいスクリプトならそれでも問題ないですが、大きいプログラムでやると他にもたくさんログが出ていて出力したものを見失いますよね。
なので自分はよく以下のように書いていました。
# こんなのとか
p '++++++++++++++'
p 'value'
P '++++++++++++++'
# こんな感じ
p '--- (~_~) ---'
p 'value'
p '--- (~_~) ---'
他の箇所が絶対に出さないようなものを出していました。顔文字は結構おすすめです。デバッグ中のすさんだ心がかわいい顔文字で癒される。
でもこれ毎回毎回やるのは面倒だなと思いました。
最近業務でフロントエンドをよくやっていたのもあってRubyでもconsole.logのようなものを使いたいと思うようになりました。
console.logは行番号も出力してくれて便利だと思いました。
Console.logを作る
要件はファイル名、行番号が出ること、そして好きなものを出力させられることです。
ドキュメントを調べてみると組み込みライブラリにKernelモジュールというものがあり使えそうなメソッドがありましたので、出来上がったものがこちら
console.rb
module Console
def self.parse_caller(at)
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
file = $1
line = $2.to_i
method = $3
[file, line, method]
end
end
def self.log(text)
puts parse_caller(caller.first)[0..1].join(':')
puts text
puts
end
end
Console.log('hoge')
# console.rb:18
# hoge
説明
# callerメソッドはメソッドの中で呼びだすとファイル名、行数、メソッド名を決まった形で返してくれる。
p caller
# ["console.rb:24:in `<main>'"]
# callerの返り値の形式が渡ってきたらparse_callerでファイル名、行数などをパースしている
parse_caller(caller.first)
Active Supportの自動require
いい感じのものができたので実際に使いたいが、毎度毎度ログを出したいだけなのに
require './console.rb'
とか書きたくない。と思っていたらActive Supportにauto requireというものがあるらしい!便利!
config/application.rbに以下のように書くと
config.autoload_paths << Rails.root.join("lib")
/lib以下にconsole.rbファイルを配置しておくだけでrequireを毎回しなくてよくなるんだそうな。
あとはconsole.rbをgitignoreするなりして。
終わり
結構勉強になった。karnelモジュール面白そうなメソッドたくさんあった。
参考
https://docs.ruby-lang.org/ja/latest/class/Kernel.html
https://blog.mirakui.com/entry/20100924/active_support
https://www.javadrive.jp/ruby/regex/ini/index4.html
追記
使ってみたら全然目立たないのでこうした方がいい
def self.log(text='')
puts '(~_~)(~_~)(~_~)(~_~)'
puts parse_caller(caller.first)[0..1].join(':')
puts text
puts
puts '(~_~)(~_~)(~_~)(~_~)'
end
追記
ricecreamめっちゃ便利
https://github.com/nodai2hITC/ricecream