Rb_include_module() doesn't call Module#included

I’m writing a c extension and I want to create a class called “World”
in C which includes a ruby module “Serializable”.

autoexec.rb

module Serializable
def self.included( otherMod )
puts “Serializable is included by #{otherMod.name}”
end
end

// World.c

rb_load( rb_str_new2(“autoexec.rb”), 0 );
VALUE klass = rb_define_class(“World”, rb_cObject);
rb_include_module( klass, rb_eval_string(“Serializable”) );

in IRB

require “World.so”
=> true

World.included_modules
=> [Serializable, Kernel]

As you can see, class “World” includes module “Serializable”, but
Serializable#included is not called.
I saw rb_mod_include (not rb_include_module) calls Module#included
explicitly in eval.c, but it’s declared as a static function, so I
can’t use it in my source code.

I think this problem is a bug, but how do you think ?

By the way, if I replace rb_include_module call with this,
Module#included is called fortunately.

VALUE args [1] = { rb_str_new2(“include Serializable”) };
rb_mod_module_eval( 1, args, klass );

But I don’t want to use eval function because it’s relatively slow.

[email protected] wrote:

By the way, if I replace rb_include_module call with this,
Module#included is called fortunately.

VALUE args [1] = { rb_str_new2(“include Serializable”) };
rb_mod_module_eval( 1, args, klass );

But I don’t want to use eval function because it’s relatively slow.

You could use rb_funcall instead.

unknown wrote:

Tim H. [email protected] wrote:

You could use rb_funcall instead.

Thanks for your reply, Tim.
But I’m not sure you mean something like this :

VALUE args [1] = { rb_str_new2("Serializable") };
rb_funcall( klass, rb_intern("include"), 1, args );

Am I correct ?

The argument to include is a module, not a string, so you’ll need to
pass the Serializable module VALUE instead of the string “Serializable”.
If you’ve defined Serializable in C, then that would be the return value
from rb_define_module_under (or whatever function you called to define
Serializable). If you’ve defined Serializable in Ruby, then you’ll have
to call rb_const_get get the value of Serializable.

Thanks for you detailed explanation, Tim.

Tim H. [email protected] wrote:

You could use rb_funcall instead.

Thanks for your reply, Tim.
But I’m not sure you mean something like this :

VALUE args [1] = { rb_str_new2("Serializable") };
rb_funcall( klass, rb_intern("include"), 1, args );

Am I correct ?