From: Simon Strandgaard Date: 2004-02-25T21:24:53+09:00 Subject: proposal: debug keyword A debug keyword which enables debug-output for a specific method. I have found its useful when there is many testcases which fails at the same time, letting me faster identify where the problem is. I think this would be a good idea to have distributed with Ruby? I am thinking of submitting an RCR, should I do this? Its syntax is debug :method [, :method]* What it does is to enable the global flag $debug. If we type 'debug :test_a1', then we get the following output server> ruby example.rb Loaded suite TestA Started test_a1(TestA): before #test_a1 A#compute, begin A#dostuff, begin A#dostuff, end A#compute, end after #test_a1 .. Finished in 0.002609 seconds. 1 tests, 1 assertions, 0 failures, 0 errors server> However if we doesn't type it, then we get our normal output. server> ruby example.rb Loaded suite TestA Started test_a1(TestA): . Finished in 0.001572 seconds. 1 tests, 1 assertions, 0 failures, 0 errors server> Its a bit hackish, but it works. server> expand -t2 debug_keyword.rb BEGIN { $debug = false } # purpose: # make it easy to enable/disable debugging # # if $debug == nil then output are disabled # if $debug != nil then output are enabled module Debuggable def printx(*args) if $debug super(*args) end end def puts(*args) if $debug super(*args) end end def p(*args) if $debug super(*args) end end def print(*args) if $debug super(*args) end end end # purpose: # enable $debug flag inside a method # # class Test # include Debuggable # def test_x; p 42; end # debug :test_x # end # Test.new.test_x #-> (before 'test_x') 42 (after 'test_x') # class Module # enable the global debug flag for just a single method def debug(*args) debug_methods = private_instance_methods(true) args.each do |symbol| name = symbol.id2name org = "_debug_"+name if debug_methods.include?(org) $stderr.puts "ERROR: already debugging method: #{name}" next end begin meth = instance_method(symbol) rescue => e $stderr.puts "ERROR: symbol2method failure, " + e.inspect next end arguments = (meth.arity != 0) ? "(*a,&b)" : "(&b)" alias_method org, name module_eval %{ def #{name}#{arguments} $stdout.puts("before ##{name}") debug, $debug = $debug, true result = #{org}#{arguments} $stdout.puts("after ##{name}") result ensure $debug = debug end private :#{org} } end end end server> server> expand -t2 example.rb require 'debug_keyword' class A include Debuggable def dostuff puts "A#dostuff, begin" puts "A#dostuff, end" end def compute puts "A#compute, begin" dostuff puts "A#compute, end" 42 end end require 'test/unit' class TestA < Test::Unit::TestCase def test_a1 assert_equal(42, A.new.compute) end debug :test_a1 # enable/disable debugging end require 'test/unit/ui/console/testrunner' Test::Unit::UI::Console::TestRunner.run(TestA, Test::Unit::UI::VERBOSE) server> -- Simon Strandgaard BTW: Thanks Nobu, Decoux for helping working the debug keyword ;-)