How to test monkey patching code?

Hi, all!

I’m wondering how to test some monkey patching code. Take the standard
library ‘jcode’
in Ruby 1.8 for example. It do some monkey patching for the core
String class when I
require it. If I want to write some unit-test or spec for it, how to
avoid it from affecting other
tests? In other words, how can I “uninstall” those monkey patching
after the test case
is finished or how can I constrain the monkey patching inside a …,
say, namespace?

I tried the following code:

orig_string = Object::String.clone

$KCODE = 'u'
require 'jcode'

# do testings

Object::String = orig_string

str1 = "foo"
str2 = String.new("foo")

# jlength are monkey patching
puts str1.jlength # => 3
puts str2.jlength # => raise NoMethodError

As I expected, str2.jlength raises NoMethodError, but str1 which is
built
by a string literal, returned 3, still being patched.

Further more, when I type those code directly in IRB, the irb fire out
some exception and exited immediately:

C:/ruby/lib/ruby/1.8/irb/ruby-token.rb:101:in Token': undefined methodancesto
rs’ for “=”:String (NoMethodError)
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:400:in lex_init' from C:/ruby/lib/ruby/1.8/irb/slex.rb:237:incall’
from C:/ruby/lib/ruby/1.8/irb/slex.rb:237:in match_io' from C:/ruby/lib/ruby/1.8/irb/slex.rb:222:inmatch_io’
from C:/ruby/lib/ruby/1.8/irb/slex.rb:76:in match' from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:287:intoken’
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:263:in lex' from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:234:ineach_top_level_stateme
nt’
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:in loop' from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:ineach_top_level_stateme
nt’
from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:in catch' from C:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:ineach_top_level_stateme
nt’
from C:/ruby/lib/ruby/1.8/irb.rb:146:in eval_input' from C:/ruby/lib/ruby/1.8/irb.rb:70:instart’
from C:/ruby/lib/ruby/1.8/irb.rb:69:in catch' from C:/ruby/lib/ruby/1.8/irb.rb:69:instart’
from C:/ruby/bin/irb:13

I suppose IRB itself is doing some monkey patching to String? So, is
there any
way to …, return to my original question, to test monkey patching
code?

Thanks!

On Feb 7, 2008 2:59 PM, pluskid [email protected] wrote:

is finished or how can I constrain the monkey patching inside a …,
# do testings

Object::String = orig_string

I would try

 orig_string = Object::String
 Object::String = Object::String.clone

 require 'jcode'

 # do testings

 Object::String = orig_string

instead.

Ie, let the modifications happen to a clone, rather than the original.
That might stop “” from generating a monkey-patched string during
testing, though.

Eivind.