ruby picture

RCR 224: temporary enabled global variable

Submitted by neoneye (Fri Feb 27 09:02:19 UTC 2004)

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
ruby picture
Comments Current voting

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


Strongly opposed 3
Opposed 8
Neutral 0
In favor 1
Strongly advocate 0
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .