P
pluskid
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!
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!