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

···

--
Posted via http://www.ruby-forum.com/.

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

···

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

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

Chris Cummer 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

···

--
Posted via http://www.ruby-forum.com/\.

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 19-Dec-07, at 9:25 PM, Wes Gamble 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 Dec 20, 2007 6:25 AM, Wes Gamble <weyus@att.net> wrote:

Chris Cummer 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.

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.

···

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

On Dec 20, 2007 6:25 AM, Wes Gamble <weyus@att.net> wrote:

Chris Cummer 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,