Monkey patching a private method?

I have found an issue with a method in a library that I’m using. I
would like to modify this method via a monkey patch, but it is a private
method, and I’m not seeming to get my patch to work.

Can the following be done? Assume a private method “meth” in class
Mod::Kls.

module Mod
class Kls
private
def meth(arg1)
@stuff = things
end
end
end

Thanks,
Wes

On 19-Dec-07, at 11:43 AM, Wes G. wrote:

private
def meth(arg1)
@stuff = things
end
end
end

Thanks,
Wes

If I understand correctly what you’re intending, you can sort’a get
around it via the following technique in which the public priv_meth()
over-rides the private one. This is not ideal though since it leaves
priv_meth() public. Is this what you’re thinking?

class TestClass
def pub_meth
return priv_meth()
end

private
def priv_meth
return “cat”
end
end

#=begin
class TestClass
def priv_meth
return “dog”
end
end
#=end

a = TestClass.new
puts a.pub_meth
puts a.priv_meth

Chris C. wrote:

If I understand correctly what you’re intending, you can sort’a get
around it via the following technique in which the public priv_meth()
over-rides the private one. This is not ideal though since it leaves
priv_meth() public. Is this what you’re thinking?

Not exactly. I need to modify the body of priv_meth, not expose it
publicly.

Wes

On Dec 20, 2007 6:25 AM, Wes G. [email protected] wrote:

Chris C. wrote:

If I understand correctly what you’re intending, you can sort’a get
around it via the following technique in which the public priv_meth()
over-rides the private one. This is not ideal though since it leaves
priv_meth() public. Is this what you’re thinking?

Not exactly. I need to modify the body of priv_meth, not expose it
publicly.

This works for me:

irb(main):013:0> class A
irb(main):014:1> def call_a; a; end
irb(main):015:1> private
irb(main):016:1> def a; “a”; end
irb(main):017:1> end
=> nil
irb(main):019:0> A.new.public_methods.grep(/\Acall_a\Z|\Aa\Z/)
=> [“call_a”]
irb(main):020:0> A.new.call_a
=> “a”
irb(main):021:0> class A
irb(main):022:1> private
irb(main):023:1> def a; “new a”; end
irb(main):024:1> end
=> nil
irb(main):025:0> A.new.public_methods.grep(/\Acall_a\Z|\Aa\Z/)
=> [“call_a”]
irb(main):026:0> A.new.call_a
=> “new a”

So it seems that the private method a can be redefined without making it
public.
Hope this helps,

Jesus.

On 19-Dec-07, at 9:25 PM, Wes G. wrote:

If I understand correctly what you’re intending, you can sort’a get
around it via the following technique in which the public priv_meth()
over-rides the private one. This is not ideal though since it leaves
priv_meth() public. Is this what you’re thinking?

Not exactly. I need to modify the body of priv_meth, not expose it
publicly.

As far as I know modifying the existing function itself isn’t
possible. Sounds like you’re talking about code injection into the
private function? That’s not quite the same as monkey patching and as
far as I know not possible in any context.

On 20-Dec-07, at 12:19 AM, Jesús Gabriel y Galán wrote:

publicly.
=> [“call_a”]
=> “new a”

So it seems that the private method a can be redefined without
making it public.
Hope this helps,

Yep, you’re right Jesús. In my example switching to:

class TestClass
private
def priv_meth
return “dog”
end
end

redefines it and keeps it private as well. So yes, it does indeed
appear that the original poster can do what they want after all.