1

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?

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
Steven Lu
  • 41,389
  • 58
  • 210
  • 364

1 Answers1

0

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.

Steven Lu
  • 41,389
  • 58
  • 210
  • 364