Chiyuan Zhang
2/7/2008 1:58:00 PM
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
method `ancesto
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:in `call'
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:in `match_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:in `token'
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:in
`each_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:in
`each_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:in
`each_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:in `start'
from C:/ruby/lib/ruby/1.8/irb.rb:69:in `catch'
from C:/ruby/lib/ruby/1.8/irb.rb:69:in `start'
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!