I need to temporarily mokey patch out a method in a certain class used
by a lib in one of my tests. That’s easy.
However, what I don’t know how to do is to restore back the orginial
(without copying in the src, of course), when I’m done. Is there any
good way to do this - that is, monkey patch temporarily, and then put
things back the way they were?
On Dec 10, 2006, at 3:35 PM, S. Robert J. wrote:
I need to temporarily mokey patch out a method in a certain class used
by a lib in one of my tests. That’s easy.
However, what I don’t know how to do is to restore back the orginial
(without copying in the src, of course), when I’m done. Is there any
good way to do this - that is, monkey patch temporarily, and then put
things back the way they were?
Sure:
#!/usr/bin/env ruby -w
class Existing
def needs_patching
:old
end
end
e = Existing.new
e.needs_patching # => :old
save the old and patch
class Existing
alias_method :saved_needs_patching, :needs_patching
def needs_patching
:new
end
end
e.needs_patching # => :new
restore the old
class Existing
undef :needs_patching
alias_method :needs_patching, :saved_needs_patching
end
e.needs_patching # => :old
END
Hope that helps.
James Edward G. II
Hi –
On Mon, 11 Dec 2006, S. Robert J. wrote:
I need to temporarily mokey patch out a method in a certain class used
by a lib in one of my tests. That’s easy.
However, what I don’t know how to do is to restore back the orginial
(without copying in the src, of course), when I’m done. Is there any
good way to do this - that is, monkey patch temporarily, and then put
things back the way they were?
I reply under mild protest, as I detest the term “monkey patching”
(and never know what people mean by it, since they mean different
things). Anyway… One way to change a method temporarily,
albeit a non-thread-safe way, is with aliases – something like:
alias newname oldname
def oldname
…
end
alias oldname newname
That was the basis of Ruby Behaviors, a package I wrote in 2001 to do
exactly this: temporary changes to core behaviors. Matz described the
alias approach at RubyConf 2001 as a “naive” way to go about it
It did however spark an interesting discussion about selector
namespaces, a discussion we’re basically still having.
There are, or were, also some other libraries on RAA that address
this. I’m afraid I don’t remember their names and am being too lazy
to look them up, but if you hunt for library stuff pertaining to
classes and methods you’ll most likely find them.
David
Hi –
On Mon, 11 Dec 2006, [email protected] wrote:
There are, or were, also some other libraries on RAA that address
this. I’m afraid I don’t remember their names and am being too lazy
to look them up, but if you hunt for library stuff pertaining to
classes and methods you’ll most likely find them.
Found it: “import-module”. It’s even thread-safe.
http://raa.ruby-lang.org/project/import_module/
David
Will this be OK even if patched and unpatched multiple times?
On Dec 10, 2006, at 4:05 PM, S. Robert J. wrote:
Will this be OK even if patched and unpatched multiple times?
You probably want to use something more robust for that. You need to
make sure you only alias the method is a saved version doesn’t
already exist.
James Edward G. II
[email protected] wrote:
In case it got lost in my reply to my reply: have a look at:
http://raa.ruby-lang.org/project/import_module/
Thanks. That’s quite a hefty module - with method am I interested in?
Hi –
On Mon, 11 Dec 2006, James Edward G. II wrote:
On Dec 10, 2006, at 4:05 PM, S. Robert J. wrote:
Will this be OK even if patched and unpatched multiple times?
You probably want to use something more robust for that. You need to make
sure you only alias the method is a saved version doesn’t already exist.
In case it got lost in my reply to my reply: have a look at:
http://raa.ruby-lang.org/project/import_module/
David
Hi –
On Mon, 11 Dec 2006, S. Robert J. wrote:
[email protected] wrote:
In case it got lost in my reply to my reply: have a look at:
http://raa.ruby-lang.org/project/import_module/
Thanks. That’s quite a hefty module - with method am I interested in?
I’m thinking something like (untested):
module M
def join
“I’m a new version of join!”
end
end
arr = [1,2,3]
Array.import_module(M) do
puts foo.join # I’m a new version of join!
end
puts foo.join # 123
so that you’d be temporarily layering different versions of the
method(s).
David
On 12/11/06, [email protected] [email protected] wrote:
I reply under mild protest, as I detest the term “monkey patching”
+1
martin