Comment on this RCR (edit wiki page) | RCRchive home

RCR 224: temporary enabled global variable

submitted by neoneye on Fri Feb 27 2004 04:23:19 AM -0800

Status: withdrawn


Abstract

turn a global variable on before invokation of a method call, and restore its value when the method returns.

Problem

while debugging testcases, then you sometimes want verbose output, and other times you want no output. However its not easy to enable/disable output!

Proposal

Above situation could be solved by letting a global variable control when the debug_puts outputs to stdout.

The syntax could be like

temporary_enable(variable_name, methods)
Below is a simplified copy of a testcase of mine. The debug controls a global variable, which controls when to output debug information. I can easily control what is going on by inserting or removing comments.
class TestScanner < Common::TestCase
  module Works
    include ExercisesSequence
    include ExercisesAlternation
    include ExercisesRepeat
  end 
  module Todo
    include ExercisesRepeatNested 
    debug :test_repeat_nested4
    undef test_repeat_nested4   # activate_next set wrong node as DONE
    
    debug :test_repeat_nested2
    #debug :test_repeat_nested3
    #undef test_repeat_nested2   # activate_next fix cause trouble
    #undef test_repeat_nested3   # activate_next fix cause trouble
  end
  include Works
  include Todo
end

Analysis

The temporary_enable method should probably be added to the class Module, in order to make it usable within modules.

Implementation

class Module
  def temporary_enable(variable, *method_names)
    temp_methods = private_instance_methods(true)
    method_names.each do |symbol| 
      name = symbol.id2name
      org = "_debug_"+name
      if temp_methods.include?(org)
        $stderr.puts "ERROR: already enabled 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}
          old, $#{variable} = $#{variable}, true
          return #{org}#{arguments}
        ensure
          $#{variable} = old
        end
        private :#{org}
      }
    end
  end
end

if $0 == __FILE__
  $global = false
  class A
    def test
      puts "A#test  global=#{$global}"
    end
    #temporary_enable("global", :test)
  end
  A.new.test
end

Vote for this RCR

Strongly opposed [3]
Opposed [8]
Neutral [0]
In favor [1]
Strongly advocate [0]

Change the status of this RCR to:

accepted

rejected

withdrawn


Add comments here

This RCR seems very specialized for a single purpose without general applicability. Furthermore, this seems like a good fit for something like log4r where you can easily control the level of logging output at whatever granularity you wish. Or use AspectR to add this to a list of methods. -- JimWeirich

The implementation can also be done using the upcoming hook mechanism, which IMHO makes this RCR superfluous.

-- Robert Klemme


Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog