Question

I only wanted to allow one instance of my C extension class to be made, so I wanted to include the singleton module.

void Init_mousetest() {
    VALUE mouseclass = rb_define_class("MyMouse",rb_cObject);
    rb_require("singleton");
    VALUE singletonmodule = rb_const_get(rb_cObject,rb_intern("Singleton"));
    rb_include_module(mouseclass,singletonmodule);

    rb_funcall(singletonmodule,rb_intern("included"),1,mouseclass);
### ^ Why do I need this line here?

    rb_define_method(mouseclass,"run",method_run,0);
    rb_define_method(mouseclass,"spawn",method_spawn,0);
    rb_define_method(mouseclass,"stop",method_stop,0);
}

As I understand it, what that line does is the same as Singleton.included(MyMouse), but if I try to invoke that, I get

irb(main):006:0> Singleton.included(MyMouse)
NoMethodError: private method `included' called for Singleton:Module
        from (irb):6
        from C:/Ruby19/bin/irb:12:in `<main>'

Why does rb_include_module behave differently than I would expect it to? Also any tangential discussions/explanations or related articles are appreciated. Ruby beginner here.

Also it seems like I could have just kept my extension as simple as possible and just hack some kind of interface later on to ensure I only allow one instance. Or just put my mouse related methods into a module... Any of that make sense?

Was it helpful?

Solution

according to http://www.groupsrv.com/computers/about105620.html the rb_include_module() is actually just Module#append_features.

Apparently Module#include calls Module#append_features and Module#included. So in our C code we must also call included. Since clearly something important happens there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top