[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

re-define class method

David Chelimsky

7/13/2006 2:59:00 AM

I've got the following:

module ClassMethods
def class_method
"Class method"
end
end

class Thing
extend ClassMethods
end

Thing.class_method
=> "Class method"

... and I want to change the behaviour of that method at runtime. I
tried this:

Thing.send(:define_method, :class_method, lambda{ "replaced" })

... but I still get this:

Thing.class_method
=> "Class method"

Am I close? What's the right way to do this?

Thanks,
David

9 Answers

David Chelimsky

7/13/2006 3:09:00 AM

0

On Jul 12, 2006, at 9:58 PM, David Chelimsky wrote:

> I've got the following:
>
> module ClassMethods
> def class_method
> "Class method"
> end
> end
>
> class Thing
> extend ClassMethods
> end
>
> Thing.class_method
> => "Class method"
>
> ... and I want to change the behaviour of that method at runtime. I
> tried this:
>
> Thing.send(:define_method, :class_method, lambda{ "replaced" })
>
> ... but I still get this:
>
> Thing.class_method
> => "Class method"
>
> Am I close? What's the right way to do this?


OK - I've discovered that I can do this:

Thing.class.send(:define_method, :other_method, lambda{ "other" })
Thing.other_method
=> "other"

and even redefine it:

Thing.class.send(:define_method, :other_method, lambda{ "other
redefined" })
Thing.other_method
=> "other redefined"

but if I try this:

Thing.class.send(:define_method, :class_method, lambda{ "replaced" })
Thing.class_method
=> "Class method"

So it looks like I can replace class methods that I define at
runtime, but not the ones that were defined at load-time. Is that
correct? Am I missing a step?

Thanks,
David



David Chelimsky

7/13/2006 10:24:00 AM

0

Well, I discovered the solution, thanks to our friend google, and got
a much better understanding of singleton classes (though the fog
hasn't completely dissipated). For anyone interested:

thing_singleton_class = class << Thing; self; end
thing_singleton_class.send(:define_method, :class_method, proc
{ "replaced" })

Thing.class_method
=> "replaced"

Cheers,
David

On Jul 12, 2006, at 10:08 PM, David Chelimsky wrote:

> On Jul 12, 2006, at 9:58 PM, David Chelimsky wrote:
>
>> I've got the following:
>>
>> module ClassMethods
>> def class_method
>> "Class method"
>> end
>> end
>>
>> class Thing
>> extend ClassMethods
>> end
>>
>> Thing.class_method
>> => "Class method"
>>
>> ... and I want to change the behaviour of that method at runtime.
>> I tried this:
>>
>> Thing.send(:define_method, :class_method, lambda{ "replaced" })
>>
>> ... but I still get this:
>>
>> Thing.class_method
>> => "Class method"
>>
>> Am I close? What's the right way to do this?
>
>
> OK - I've discovered that I can do this:
>
> Thing.class.send(:define_method, :other_method, lambda{ "other" })
> Thing.other_method
> => "other"
>
> and even redefine it:
>
> Thing.class.send(:define_method, :other_method, lambda{ "other
> redefined" })
> Thing.other_method
> => "other redefined"
>
> but if I try this:
>
> Thing.class.send(:define_method, :class_method, lambda{ "replaced" })
> Thing.class_method
> => "Class method"
>
> So it looks like I can replace class methods that I define at
> runtime, but not the ones that were defined at load-time. Is that
> correct? Am I missing a step?
>
> Thanks,
> David
>
>
>


dblack

7/13/2006 10:33:00 AM

0

David Chelimsky

7/13/2006 11:13:00 AM

0

On Jul 13, 2006, at 5:33 AM, dblack@wobblini.net wrote:

> On Thu, 13 Jul 2006, David Chelimsky wrote:
>
>> thing_singleton_class = class << Thing; self; end
>> thing_singleton_class.send(:define_method, :class_method, proc
>> { "replaced" })
>>
>> Thing.class_method
>> => "replaced"
>
> Don't forget that you can do this much more concisely (unless you have
> a specific need to go the long way round):
>
> def Thing.class_method
> "replaced"
> end

Thanks David. I definitely appreciate the conciseness of this, and
will use that when I know the type. The problem I'm working on
requires a solution to replacing singleton methods on arbitrary types
at runtime, so I think I have to stick w/ the more cryptic version.
Unless you have a different suggestion - I'm just getting my head
wrapped around metaprogramming and singleton classes, so all
suggestions are most welcome.

Thanks,
David


dblack

7/13/2006 11:24:00 AM

0

David Chelimsky

7/13/2006 12:00:00 PM

0

On Jul 13, 2006, at 6:24 AM, dblack@wobblini.net wrote:
>>> On Thu, 13 Jul 2006, David Chelimsky wrote:
>>>> thing_singleton_class = class << Thing; self; end
>>>> thing_singleton_class.send(:define_method, :class_method, proc
>>>> { "replaced" })
>>>> Thing.class_method
>>>> => "replaced"
>
> I would personally tend to use class_eval and define_method without
> send:
>
> meth = "class_method"
> l = lambda { "replaced" }
> (class << Thing; self; end).class_eval { define_method(meth,&l) }

Excellent! Much cleaner.

Thanks,
David

Sean O'Halpin

7/13/2006 12:48:00 PM

0

On 7/13/06, David Chelimsky <david@objectmentor.com> wrote:
> On Jul 13, 2006, at 5:33 AM, dblack@wobblini.net wrote:
>
> > On Thu, 13 Jul 2006, David Chelimsky wrote:
> >
> >> thing_singleton_class = class << Thing; self; end
> >> thing_singleton_class.send(:define_method, :class_method, proc
> >> { "replaced" })
> >>
> >> Thing.class_method
> >> => "replaced"
> >
> > Don't forget that you can do this much more concisely (unless you have
> > a specific need to go the long way round):
> >
> > def Thing.class_method
> > "replaced"
> > end
>
> Thanks David. I definitely appreciate the conciseness of this, and
> will use that when I know the type. The problem I'm working on
> requires a solution to replacing singleton methods on arbitrary types
> at runtime, so I think I have to stick w/ the more cryptic version.
> Unless you have a different suggestion - I'm just getting my head
> wrapped around metaprogramming and singleton classes, so all
> suggestions are most welcome.
>
> Thanks,
> David
>

You can use David's method like this:

def redefine_method_for(klass)
def klass.class_method
"replaced"
end
end

redefine_method_for Thing

p Thing.class_method
#=> "replaced"

Regards,
Sean

David Chelimsky

7/13/2006 2:01:00 PM

0

On Jul 13, 2006, at 7:47 AM, Sean O'Halpin wrote:
> On 7/13/06, David Chelimsky <david@objectmentor.com> wrote:
>> On Jul 13, 2006, at 5:33 AM, dblack@wobblini.net wrote:
>> > Don't forget that you can do this much more concisely (unless
>> you have
>> > a specific need to go the long way round):
>> >
>> > def Thing.class_method
>> > "replaced"
>> > end
>
> You can use David's method like this:
>
> def redefine_method_for(klass)
> def klass.class_method
> "replaced"
> end
> end
>
> redefine_method_for Thing
>
> p Thing.class_method
> #=> "replaced"

Unfortunately (actually, rather fortunately ;) ), both the class and
the method name are determined at run time. David's dynamic
suggestion (elsewhere in this thread) is working quite well.

Cheers, and thanks for the help!

David

rightwingerssuck

9/4/2008 2:32:00 PM

0

On Sep 3, 10:41 pm, 4657 Dead <zepp22114...@finestplanet.com> wrote:
> On Wed, 3 Sep 2008 22:11:35 -0500, "Jorge Duhbya Arbusto, POTUS
>
> \(Retired\)" <cleanin_the_stab...@fakeranch.tx> wrote:
> >Buhwahaha wrote:
> >> "WE GOT YOUR CHANGE" <progressive_libertar...@yahoo.com> wrote in
> >> message
> >>news:8ea1f2d7-5c6f-4d05-bc42-d2d7195c14ac@b2g2000prf.googlegroups.com...
> >>> (lipstick)
>
> >>> LOL!!
>
> >>> She's wonderful.
>
> >> She's like................TOTALLY AWESOME!!!!
>
> >Not really....
>
> Well, she can stir up the wing nuts.
>
> Of course, there aren't nearly as many of those as there used to be...
>
I'm beginning to figure out why the right wingers have fucked this
country so much. They don't use their BRAINS for thinking...