[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Add a method to a class at runtime?

bwv549

8/30/2007 6:55:00 PM


module SomeModule
def happy?
puts 'yes'
end
end

# I can do this:
some_object.extend(SomeModule)
some_object.happy? # -> 'yes'

# But I really need to give the class the method (not just instances)
# because I have a collection of hundreds of thousands of objects
# and need them all to have the method quickly.

# The problem is that I don't know the class that needs to include the
method
# until runtime!

# This won't work:

some_object.class.include(SomeModule)
# -> NoMethodError: private method `include' called for <SomeClass>

# What is the workaround to add a method to a class (known only at
runtime)?

Thanks

4 Answers

bwv549

8/30/2007 6:59:00 PM

0

Note to self,
class_eval or module_eval should work

# from ri class_eval:
class Thing
end
a = %q{def hello() "Hello there!" end}
Thing.module_eval(a)
puts Thing.new.hello()
Thing.module_eval("invalid code", "dummy", 123)


Phrogz

8/30/2007 8:28:00 PM

0

On Aug 30, 12:58 pm, bwv549 <jtpri...@gmail.com> wrote:
> # from ri class_eval:
> class Thing
> end
> a = %q{def hello() "Hello there!" end}
> Thing.module_eval(a)
> puts Thing.new.hello()
> Thing.module_eval("invalid code", "dummy", 123)

And no need to use strings:
module Joi
def happy?; true; end
end

class Foo; end

f1 = Foo.new
f2 = Foo.new

f2.class.class_eval{ include Joi }
p f1.happy?
#=> true

Stefan Rusterholz

8/30/2007 8:33:00 PM

0

bwv549 wrote:
> module SomeModule
> def happy?
> puts 'yes'
> end
> end
>
> # I can do this:
> some_object.extend(SomeModule)
> some_object.happy? # -> 'yes'
>
> # But I really need to give the class the method (not just instances)
> # because I have a collection of hundreds of thousands of objects
> # and need them all to have the method quickly.
>
> # The problem is that I don't know the class that needs to include the
> method
> # until runtime!
>
> # This won't work:
>
> some_object.class.include(SomeModule)
> # -> NoMethodError: private method `include' called for <SomeClass>
>
> # What is the workaround to add a method to a class (known only at
> runtime)?
>
> Thanks

You have a misunderstanding here. *All* methods are added to classes at
runtime, since that's the only "time" ruby has (there is no compile
time). Of course, C-extensions are excluded from this.
You can always reopen a class:
class Array
def foo; "foo!"; end
end
[].foo # => "foo!"

Regards
Stefan
--
Posted via http://www.ruby-....

Stefan Rusterholz

8/30/2007 8:36:00 PM

0

Stefan Rusterholz wrote:
> bwv549 wrote:
>> module SomeModule
>> def happy?
>> puts 'yes'
>> end
>> end
>>
>> # I can do this:
>> some_object.extend(SomeModule)
>> some_object.happy? # -> 'yes'
>>
>> # But I really need to give the class the method (not just instances)
>> # because I have a collection of hundreds of thousands of objects
>> # and need them all to have the method quickly.
>>
>> # The problem is that I don't know the class that needs to include the
>> method
>> # until runtime!
>>
>> # This won't work:
>>
>> some_object.class.include(SomeModule)
>> # -> NoMethodError: private method `include' called for <SomeClass>
>>
>> # What is the workaround to add a method to a class (known only at
>> runtime)?
>>
>> Thanks
>
> You have a misunderstanding here. *All* methods are added to classes at
> runtime, since that's the only "time" ruby has (there is no compile
> time). Of course, C-extensions are excluded from this.
> You can always reopen a class:
> class Array
> def foo; "foo!"; end
> end
> [].foo # => "foo!"
>
> Regards
> Stefan

That one went off too early, The missing paragraph:
As for your problem: you can use include, e.g. via
YourClass.send(:include, ModuleName), if you have the classname as
Symbol or String, see Module#const_get.

Regards
Stefan
--
Posted via http://www.ruby-....