enable debugflag in module

S

Simon Strandgaard

To ease unittesting I have made a #debug keyword, which enables
the global $debug flag for the specified method.

For instance
debug :test
is roughly equivalent with
def test
$debug = true
super
$debug = false
end

The "debug" keyword works inside classes. But not within modules.
Question: How can I make "debug" work within modules ?

--
Simon Strandgaard


server> ruby a.rb
before #test
42
after #test
server> expand -t4 a.rb
class Object
# enable the global debug flag for just a single method
def self.debug(*args)
args.each{|symbol|
begin
meth = instance_method(symbol)
rescue => e
$stderr.puts "ERROR: symbol2method failure, " + e.inspect
next
end
name = symbol.id2name
org = "_debug_"+name
arguments = (meth.arity != 0) ? "(*a,&b)" : "(&b)"
module_eval <<MSG
alias #{org} #{name}
def #{name}#{arguments}
$stdout.puts("before ##{name}")
$debug = true
#{org}#{arguments}
$stdout.puts("after ##{name}")
ensure
$debug = nil
end
private :#{org}
MSG
}
end
end

class Test
module A
def test
p 42
end
#debug :test # Why does'nt this work?
end

include A
debug :test
end

Test.new.test
server>
 
N

nobu.nokada

Hi,

At Wed, 21 Jan 2004 06:55:01 +0900,
Simon said:
class Object
# enable the global debug flag for just a single method
def self.debug(*args)

Should be Module's instance method.
#{org}#{arguments}
$stdout.puts("after ##{name}")

This discards the result of the original method.

And you'd better to check the method already "debugged" to get
rid of infinite recursion.


class Module
# enable the global debug flag for just a single method
def debug(*args)
debug_methods = private_instance_methods(true)
args.each{|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
alias_method org, name
module_eval %{
def #{name}(*a, &b)
$stdout.puts("before ##{name}")
debug, $debug = $debug, true
result = #{org}(*a, &b)
$stdout.puts("after ##{name}")
result
ensure
$debug = debug
end
private :#{org}
}
}
end
end

class Test
module A
def test
p 42
end
debug :test
end

include A
debug :test # Error and skipped
end

Test.new.test
 
S

Simon Strandgaard

At Wed, 21 Jan 2004 06:55:01 +0900,


Should be Module's instance method.


This discards the result of the original method.
ok


And you'd better to check the method already "debugged" to get
rid of infinite recursion.

I have briefly thought about this, but didn't knew how/where
to begin. But you have solved it! Thanks.


[snip]
alias_method org, name
module_eval %{

^^^^ NICE.. wasn't aware of this.

def #{name}(*a, &b)

^^^^^^^^
By doing so, then Test::Unit rejects
the method. I use #{name}#{arguments}.

Educational.. Now 'debug' is even more useful. Thanks Nobu.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

proposal: debug keyword 12
overload method in module_eval, how? 12
class#methods how ? 3
Python equivalent for C module 10
[ANN] main-4.0.0 (for avdi) 0
ANN main-4.4.0 0
[ANN] main-2.8.3 2
[ANN] main-3.0.1 0

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top