Rubyでのデバッグテクニック
デバッグモードを使う
Rubyにはグローバル変数$DEBUGが定義されている。これは、Rubyインタプリタに--debugオプションを渡すか、コード$DEBUGをtrueにすることで有効になる。
loggerを使う
Ruby標準ライブラリのLoggerを使って、ログデータをファイルまたは別のストリームに出力する。
ログレベルはFATAL,ERROR,WARN,INFO,DEBUGの5段階。
require 'logger'
log = Logger.new(STDOUT)
#log.level = Logger::ERROR
#log.level = Logger::FATAL
#log.level = Logger::WARN
#log.level = Logger::INFO
log.level = Logger::DEBUG
log.error("Error!!");
log.fatal("Fatal!!");
log.debug("Created logger")
log.info("Program started");
log.warn("Nothing to do!");
出力
E, [2008-09-25T21:37:18.168000 #5664] ERROR -- : Error!! F, [2008-09-25T21:37:18.168000 #5664] FATAL -- : Fatal!! D, [2008-09-25T21:37:18.168000 #5664] DEBUG -- : Created logger I, [2008-09-25T21:37:18.168000 #5664] INFO -- : Program started W, [2008-09-25T21:37:18.178000 #5664] WARN -- : Nothing to do!
Loggerは期間あるいはファイルサイズを元にrotateしてログファイルを交換することもできる。
Logger.new('logfile.log', 'monthly') #月ごとにログファイルを交換 他にdaily, weeklyが指定できる。
Logger.new('logfile.log', 5, 100 * 1024 * 1024) #100MBのログを5つまで保持する
Logger.new('logfile.log', 0, 100 * 1024 * 1024) #100MBでログファイルを交換
datetime_formatを変更することで日付フォーマットを変更できる。
log = Logger.new(STDOUT) log.datetime_format = "%Y-%m-%d %H:%M:%S"
さらに、Logger::Formatterのcallをオーバーライドすれば、さらに出力を変更できる。
Kernel#callerでコールスタックを調べる。
Kernel#callerによって呼び出し元のメソッドを調べることができる。
class ClassA def ClassA.some_methodA ClassB.some_methodB end end class ClassB def ClassB.some_methodB ClassC.do_action end end class ClassC def ClassC.do_action puts 'show trace back' caller.each do |c| puts c end end end ClassA.some_methodA
出力
show trace back trace_back.rb:9:in `some_methodB' trace_back.rb:3:in `some_methodA' trace_back.rb:22
Breakpointライブラリを使用する
メソッドbreakpointを実行すると、irbの対話型のRubyセッションに切り替わります。
require 'breakpoint'
$KCODE ='sjis'
class Foo
def initialize(init_val)
@instance_var = init_val
end
def bar
test_var = @instance_var
puts 'before break'
breakpoint
puts 'after break'
puts "test_var: #{test_var}, @instance_var: #{@instance_var}"
end
end
f = Foo.new('start')
f.bar
プロファイリング機能を使用する
アプリケーションにRubyプロファイラをインクルードすると、rubyはアプリケーション終了後に標準エラー出力にレポートを出力する。
require 'profile'
total=0
('a'..'zz').each do |seq|
['a', 'b', 'c'].each do |i|
if seq.index(i)
total += 1
break
end
end
end
puts "Total: #{total}"
出力
Total: 150 % cumulative self self total time seconds seconds calls ms/call ms/call name 48.00 0.12 0.12 702 0.17 0.27 Array#each 24.00 0.18 0.06 1952 0.03 0.03 String#index 24.00 0.24 0.06 1 60.00 250.00 Range#each 4.00 0.25 0.01 150 0.07 0.07 Fixnum#+ 0.00 0.25 0.00 1 0.00 0.00 String#<=> 0.00 0.25 0.00 702 0.00 0.00 String#succ 0.00 0.25 0.00 1 0.00 0.00 Kernel.puts 0.00 0.25 0.00 2 0.00 0.00 IO#write 0.00 0.25 0.00 1 0.00 0.00 Fixnum#to_s 0.00 0.25 0.00 1 0.00 250.00 #toplevel
プロファイラは最も時間のかかるメソッドからリストアップする。
| Print article | This entry was posted by motoki on 9月 25, 2008 at 11:19 pm, and is filed under ruby. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |