Monkey patching a private method?

W

Wes Gamble

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
 
C

Chris Cummer

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


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
 
W

Wes Gamble

Chris said:
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
 
C

Chris Cummer

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.
 
J

Jesús Gabriel y Galán

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.
 
C

Chris Cummer

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
=3D> nil
irb(main):019:0> A.new.public_methods.grep(/\Acall_a\Z|\Aa\Z/)
=3D> ["call_a"]
irb(main):020:0> A.new.call_a
=3D> "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
=3D> nil
irb(main):025:0> A.new.public_methods.grep(/\Acall_a\Z|\Aa\Z/)
=3D> ["call_a"]
irb(main):026:0> A.new.call_a
=3D> "new a"

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

Yep, you're right Jes=FAs. 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 =20
appear that the original poster can do what they want after all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top