Accessing the method visibility
I took on the task to make the looksee gem work with ruby 2.3 and 2.4. Unfortunately, some features were not directly accessible in ruby, so a C extension was made, which includes some ruby internals.
For ruby 2.2 support, internal.h and method.h were included. For ruby 2.3, I found I need id_table.h at least, but I did not fully succeed making it work.
In a short email thread, koichi san suggested it would be better to request to add the necessary public interface to ruby so that looksee would not need internals.
looksee creates these new methods from ruby internals:
rb_define_method(mMRI, "internal_superclass", Looksee_internal_superclass, 1); rb_define_method(mMRI, "internal_class", Looksee_internal_class, 1); rb_define_method(mMRI, "internal_public_instance_methods", Looksee_internal_public_instance_methods, 1); rb_define_method(mMRI, "internal_protected_instance_methods", Looksee_internal_protected_instance_methods, 1); rb_define_method(mMRI, "internal_private_instance_methods", Looksee_internal_private_instance_methods, 1); rb_define_method(mMRI, "internal_undefined_instance_methods", Looksee_internal_undefined_instance_methods, 1); rb_define_method(mMRI, "included_class?", Looksee_included_class_p, 1); rb_define_method(mMRI, "singleton_class?", Looksee_singleton_class_p, 1); rb_define_method(mMRI, "singleton_instance", Looksee_singleton_instance, 1); rb_define_method(mMRI, "real_module", Looksee_real_module, 1); rb_define_method(mMRI, "module_name", Looksee_module_name, 1);
It uses the following macros to find the method visibility and whether it has been redefined:
Ideally, a ruby method that returns visibility should return one of the following values:
[:public, :protected, :private, :undefined, :overridden]
We are using other ruby macros to find where and within which module or class the method is defined.
RCLASS_SUPER(internal_class) CLASS_OF(object) RCLASS_M_TBL(klass) SPECIAL_CONST_P(object) BUILTIN_TYPE(object) FL_TEST(singleton_class, FL_SINGLETON) RCLASS_IV_TBL(singleton_class) RBASIC(module_or_included_class)->klass
You can see what I have tried for ruby 2.3: https://github.com/oggy/looksee/pull/36/files#diff-d5ef4b0cfbd5a6712f37dfa7ffbe2130
I cannot use
rb_id_table_foreach, which suggests that I need to import much ruby code into the extension. I prefer not to include more C into this gem.
So I am trying to extract
struct rb_id_table*, but I am getting a deferencing incomplete type error.