Redefine Kernel method

I would like to redefine the method Kernel#rand inside a test method, and
reset it in the end again.
But everything I try fails. If I redefine it outside my module and class,
it works. But I would like to do it inside my test method.

Thx for any hint.
Daniel

koboi wrote:

I would like to redefine the method Kernel#rand inside a test method, and
reset it in the end again.
But everything I try fails. If I redefine it outside my module and class,
it works. But I would like to do it inside my test method.

def meth
    m = proc { 5 }
    Kernel.module_eval( "alias :rand_old :rand" )
    Kernel.module_eval( "def rand; #{m.call}; end" )
    puts rand
    Kernel.module_eval( "alias :rand :rand_old" )
    Kernel.module_eval( "remove_method( :rand_old ) " )
end

meth
puts rand

I hope this moves you in the right direction,

Zach

It moves in the right direction, yes, thanks.
But still, it doesn't work as I would like. If I want to count, how many
times the method is called, the Proc is evaluated only once, so the count
is always 1.
Example:
  @count = 0
  m = proc { @count += 1; 5 }
  #...
  #call rand several times
  p @count -> 1

Any suggestions.
thanks, daniel

koboi wrote:

It moves in the right direction, yes, thanks.
But still, it doesn't work as I would like. If I want to count, how many
times the method is called, the Proc is evaluated only once, so the count
is always 1.
Example:
  @count = 0
  m = proc { @count += 1; 5 }
  #...
  #call rand several times
  p @count -> 1

I'm going to repost after i figure this one out, the problem with my first post (and i apologize for posting inaccurate code), was that the "#{m.call}" was getting evaluated in the 'module_eval( "..." )' and it wasn't actually getting called when rand got called.

Kernel.module_eval( "def rand; #{m.call}; end" )

Will have rand return the value of m.call. It will always return the same thing, because m.call is evaluated in the String, and not when rand is called.

     m = proc { 50 }
     def rand; #{m.call}; end

is the same as:

     def rand; 50; end

working on a solution,

Zach

Ok, here's what you want Daniel;

def meth
    str =<<-"ENDSTR"
       alias :rand_old :rand
       @@rand_call_count = 0
       def rand
          @@rand_call_count += 1
          puts @@rand_call_count
          rand_old
       end
    ENDSTR
    Kernel.module_eval( str )
    rand
    Kernel.module_eval( "alias :rand :rand_old" )
    Kernel.module_eval( "remove_method( :rand_old ) " )
end

meth

This will still allow rand to return the correct value, and it will get count for you.

This is a cleaner solution then before.

HTH,

Zach

Just used your new version, it works now. Thanks a lot for your help.

There is only one little change:
   ....
   def rand(max = 0)
     ....

Thx,
Daniel