Add a method to a class at runtime?

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

What is the workaround to add a method to a class (known only at

runtime)?

Thanks

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)

On Aug 30, 12:58 pm, bwv549 [email protected] 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

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

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

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

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