[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

overload method in module_eval, how?

Simon Strandgaard

11/10/2003 12:09:00 PM

I want to overload a testcase method with debug-enabling wrapper.
But it doesn't seems like my Object#debug method gets called at all.

Any ideas how to do this ?

--
Simon Strandgaard


server> ruby test_dbg.rb
Loaded suite TestDbg
Started
F
Finished in 0.008819 seconds.

1) Failure:
default_test(TestDbg) [test_dbg.rb:31]:
No tests were specified.

1 tests, 1 assertions, 1 failures, 0 errors
server> expand -t2 test_dbg.rb
require 'test/unit'

class Object
def self.debug(*args)
args.each{|method|
name = method.id2name
org = "_debug_"+name
code=<<MSG
alias #{org} #{name}
def #{name}(*a,&b)
$stdout.puts("before")
#{org}(*a,&b)
$stdout.puts("after")
end
private :#{org}
MSG
module_eval code
}
end
end

class TestDbg < Test::Unit::TestCase
def test_x
assert_equal(true, true)
end
debug :test_x # uncomment me, and it works!
end

if $0 == __FILE__
require 'test/unit/ui/console/testrunner'
Test::Unit::UI::Console::TestRunner.run(TestDbg)
end
server>
12 Answers

ts

11/10/2003 12:28:00 PM

0

>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:

S> class Object
S> def self.debug(*args)
S> args.each{|method|
S> name = method.id2name
S> org = "_debug_"+name
S> code=<<MSG
S> alias #{org} #{name}
S> def #{name}(*a,&b)

def #{name}(&b)

S> $stdout.puts("before")
S> #{org}(*a,&b)

#{org}(&b)

S> $stdout.puts("after")
S> end
S> private :#{org}
S> MSG
S> module_eval code
S> }
S> end
S> end

S> class TestDbg < Test::Unit::TestCase
S> def test_x

The arity for a test method must be == 0

--

Guy Decoux

Simon Strandgaard

11/10/2003 12:43:00 PM

0

On Mon, 10 Nov 2003 13:27:41 +0100, ts wrote:

>>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:
[snip]
> S> def #{name}(*a,&b)
>
> def #{name}(&b)
[snip]
> S> #{org}(*a,&b)
>
> #{org}(&b)
>
> The arity for a test method must be == 0

Thanks Guy.

Though, now I don't understand why my example didn't work?
How to make it general so it works for an arbitrary number of arguments ?

--
Simon Strandgaard

ts

11/10/2003 12:48:00 PM

0

>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:

S> Though, now I don't understand why my example didn't work?

Because the new method that you have defined was

def test_x(*a, b)
end

This give an arity -1, and runit reject these methods it keep only methods
with a zero arity


S> How to make it general so it works for an arbitrary number of arguments ?

You *can't* give an arbitrary number of arguments for a test method


--

Guy Decoux

Simon Strandgaard

11/10/2003 2:06:00 PM

0

On Mon, 10 Nov 2003 13:47:46 +0100, ts wrote:

>>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:
>
> S> Though, now I don't understand why my example didn't work?
>
> Because the new method that you have defined was
>
> def test_x(*a, b)
> end
>
> This give an arity -1, and runit reject these methods it keep only methods
> with a zero arity
>
>
> S> How to make it general so it works for an arbitrary number of arguments ?
>
> You *can't* give an arbitrary number of arguments for a test method

DrainBammage, thats obvious. Thanks.

BTW: I wonder why the last "p instance_methods" doesn't output anything?

--
Simon Strandgaard

server> ruby test_dbg.rb
["test_x"]
Loaded suite test_dbg
Started
.
Finished in 0.002346 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
server> expand -t2 test_dbg.rb
require 'test/unit'

class Object
def self.debug(*args)
p instance_methods(false)
args.each{|method|
name = method.id2name
org = "_debug_"+name
arguments = (method.arity > 0) ? "(*a,&b)" : "(&b)"
code=<<MSG
alias #{org} #{name}
def #{name}#{arguments}
$stdout.puts("before")
#{org}#{arguments}
$stdout.puts("after")
end
private :#{org}
MSG
module_eval code
}
p instance_methods(false) # No output, why ?
end
end

class TestDbg < Test::Unit::TestCase
def test_x
assert_equal(true, true)
end
debug :test_x
end

if $0 == __FILE__
require 'test/unit/ui/console/testrunner'
Test::Unit::UI::Console::TestRunner.run(TestDbg)
end
server>

ts

11/10/2003 2:19:00 PM

0

>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:

S> BTW: I wonder why the last "p instance_methods" doesn't output anything?

I don't understand, you want to say that you don't see this ?

server> ruby test_dbg.rb
S> ["test_x"]
^^^^^^^^^^



--

Guy Decoux

Simon Strandgaard

11/10/2003 2:44:00 PM

0

On Mon, 10 Nov 2003 15:19:18 +0100, ts wrote:

>>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:
>
> S> BTW: I wonder why the last "p instance_methods" doesn't output anything?
>
> I don't understand, you want to say that you don't see this ?
>
> server> ruby test_dbg.rb
> S> ["test_x"]
> ^^^^^^^^^^

I do a print both before and after. Only the first print statement
outputs something. The second doesn't output anything?

It should output the same as the first print-statement, but I get nothing.

any ideas to what can cause such a problem ?

--
Simon Strandgaard

ts

11/10/2003 2:48:00 PM

0

>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:

S> any ideas to what can cause such a problem ?

S> args.each{|method|
S> name = method.id2name
S> org = "_debug_"+name
S> arguments = (method.arity > 0) ? "(*a,&b)" : "(&b)"

svg% ruby -e 'def test_x() end; :test_x.arity'
-e:1: undefined method `arity' for :test_x:Symbol (NoMethodError)
svg%

svg% ruby -e 'def test_x() end; p method(:test_x).arity'
0
svg%

and you can have an arity < 0



--

Guy Decoux

Simon Strandgaard

11/10/2003 3:21:00 PM

0

On Mon, 10 Nov 2003 15:48:22 +0100, ts wrote:

>>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:
>
> S> any ideas to what can cause such a problem ?
>
> S> args.each{|method|
> S> name = method.id2name
> S> org = "_debug_"+name
> S> arguments = (method.arity > 0) ? "(*a,&b)" : "(&b)"
>
> svg% ruby -e 'def test_x() end; :test_x.arity'
> -e:1: undefined method `arity' for :test_x:Symbol (NoMethodError)
> svg%
>
> svg% ruby -e 'def test_x() end; p method(:test_x).arity'
> 0
> svg%
>
> and you can have an arity < 0

changing so it becomes (arity != 0), will that be ok?

Still only the first output statement are working.
I don't understand why the successive print-statements doesn't output
anything. Any hints ?


--
Simon Strandgaard

server> ruby test_dbg.rb
["test_x"]
Loaded suite test_dbg
Started
.
Finished in 0.003568 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
server> expand -t2 test_dbg.rb
require 'test/unit'

class Object
def self.debug(*args)
p instance_methods(false)
args.each{|m|
name = m.id2name
org = "_debug_"+name
n = method(m).arity
puts "method=#{name} arity=#{n}" # No output, why ?
arguments = (n != 0) ? "(*a,&b)" : "(&b)"
code=<<MSG
alias #{org} #{name}
def #{name}#{arguments}
$stdout.puts("before")
#{org}#{arguments}
$stdout.puts("after")
end
private :#{org}
MSG
module_eval code
}
p instance_methods(false) # No output, why ?
end
end

class TestDbg < Test::Unit::TestCase
def test_x
assert_equal(true, true)
end
debug :test_x
end

require 'test/unit/ui/console/testrunner'
Test::Unit::UI::Console::TestRunner.run(TestDbg)
server>

ts

11/10/2003 3:43:00 PM

0

>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:

S> Still only the first output statement are working.
S> I don't understand why the successive print-statements doesn't output
S> anything. Any hints ?


I've given the hint : method is a Symbol, and the method Symbol#arity is
not defined.

You must first call Kernel#method with the symbol as argument and then
call arity

svg% ruby -e 'def test_x() end; method = :test_x; p method(method).class'
Method
svg%

svg% ruby -e 'def test_x() end; method = :test_x; p method(method).arity'
0
svg%


--

Guy Decoux

Simon Strandgaard

11/10/2003 4:11:00 PM

0

On Mon, 10 Nov 2003 16:43:20 +0100, ts wrote:

>>>>>> "S" == Simon Strandgaard <qj5nd7l02@sneakemail.com> writes:
>
> S> Still only the first output statement are working.
> S> I don't understand why the successive print-statements doesn't output
> S> anything. Any hints ?
>
>
> I've given the hint : method is a Symbol, and the method Symbol#arity is
> not defined.
>
> You must first call Kernel#method with the symbol as argument and then
> call arity
>
> svg% ruby -e 'def test_x() end; method = :test_x; p method(method).class'
> Method
> svg%
>
> svg% ruby -e 'def test_x() end; method = :test_x; p method(method).arity'
> 0
> svg%

I think I do symbol2method lookup wrong. How does I lookup
the symbol in the instance namespace ?

--
Simon Strandgaard


server> ruby test_dbg.rb
["test_x"]
symbol = test_x
ERROR: symbol2method failure, #<NameError: undefined method `test_x' for class `Class'>
method =
method.class = NilClass
Loaded suite test_dbg
Started
.
Finished in 0.002409 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
server> expand -t2 test_dbg.rb
require 'test/unit'

class Object
def self.debug(*args)
p instance_methods(false)
args.each{|symbol|
puts "symbol = #{symbol}"

begin
meth = method(symbol)
rescue => e
puts "ERROR: symbol2method failure, " + e.inspect
end
puts "method = #{meth}"
puts "method.class = #{meth.class}"

n = meth.arity
puts "arity=#{n}"

name = symbol.id2name
org = "_debug_"+name
arguments = (n != 0) ? "(*a,&b)" : "(&b)"
code=<<MSG
alias #{org} #{name}
def #{name}#{arguments}
$stdout.puts("before")
#{org}#{arguments}
$stdout.puts("after")
end
private :#{org}
MSG
module_eval code
}
p instance_methods(false)
end
end

class TestDbg < Test::Unit::TestCase
def test_x
assert_equal(true, true)
end
debug :test_x
end

require 'test/unit/ui/console/testrunner'
Test::Unit::UI::Console::TestRunner.run(TestDbg)
server>