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 ;-)