Project

General

Profile

Feature #12655

Accessing the method visibility

Added by mathieujobin (Mathieu Jobin) about 4 years ago. Updated 9 months ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:76732]

Description

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:

UNDEFINED_METHOD_ENTRY_P(me)
METHOD_ENTRY_VISI(me)

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 st_table from struct rb_id_table*, but I am getting a deferencing incomplete type error.

Please help.

Also available in: Atom PDF