[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Monkey patching a private method?

Wes Gamble

12/19/2007 7:44:00 PM

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

5 Answers

Chris Cummer

12/20/2007 3:04:00 AM

0

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


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

Wes Gamble

12/20/2007 5:26:00 AM

0

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

Chris Cummer

12/20/2007 8:07:00 AM

0

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.


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.

Jesús Gabriel y Galán

12/20/2007 8:19:00 AM

0

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,

Jesus.

Chris Cummer

12/20/2007 1:21:00 PM

0


On 20-Dec-07, at 12:19 AM, Jes=FAs Gabriel y Gal=E1n 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 =20
>>> 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
> =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.