Add Module#undefined_instance_methods

Implements [Feature #12655]

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
This commit is contained in:
Jeremy Evans 2022-06-06 09:57:32 -07:00 committed by GitHub
parent b737998d25
commit 7cda7fbbdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2022-06-07 01:57:54 +09:00
Merged: https://github.com/ruby/ruby/pull/5733

Merged-By: jeremyevans <code@jeremyevans.net>
5 changed files with 38 additions and 0 deletions

View File

@ -112,6 +112,7 @@ Note: We're only listing outstanding class updates.
* Module.used_refinements has been added. [[Feature #14332]]
* Module#refinements has been added. [[Feature #12737]]
* Module#const_added has been added. [[Feature #17881]]
* Module#undefined_instance_methods has been added. [[Feature #12655]]
* Proc
* Proc#dup returns an instance of subclass. [[Bug #17545]]
@ -235,6 +236,7 @@ The following deprecated APIs are removed.
## Miscellaneous changes
[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
[Feature #14332]: https://bugs.ruby-lang.org/issues/14332

24
class.c
View File

@ -1638,6 +1638,15 @@ ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
return ins_methods_type_i(name, type, ary, METHOD_VISI_PUBLIC);
}
static int
ins_methods_undef_i(st_data_t name, st_data_t type, st_data_t ary)
{
if ((rb_method_visibility_t)type == METHOD_VISI_UNDEF) {
ins_methods_push(name, ary);
}
return ST_CONTINUE;
}
struct method_entry_arg {
st_table *list;
int recur;
@ -1807,6 +1816,21 @@ rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
}
/*
* call-seq:
* mod.undefined_instance_methods -> array
*
* Returns a list of the undefined instance methods defined in <i>mod</i>.
* The undefined methods of any ancestors are not included.
*/
VALUE
rb_class_undefined_instance_methods(VALUE mod)
{
VALUE include_super = Qfalse;
return class_instance_method_list(1, &include_super, mod, 0, ins_methods_undef_i);
}
/*
* call-seq:
* obj.methods(regular=true) -> array

View File

@ -149,6 +149,7 @@ VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_class_undefined_instance_methods(VALUE mod);
VALUE rb_special_singleton_class(VALUE);
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
VALUE rb_singleton_class_get(VALUE obj);

View File

@ -4398,6 +4398,8 @@ InitVM_Object(void)
rb_class_protected_instance_methods, -1); /* in class.c */
rb_define_method(rb_cModule, "private_instance_methods",
rb_class_private_instance_methods, -1); /* in class.c */
rb_define_method(rb_cModule, "undefined_instance_methods",
rb_class_undefined_instance_methods, 0); /* in class.c */
rb_define_method(rb_cModule, "constants", rb_mod_constants, -1); /* in variable.c */
rb_define_method(rb_cModule, "const_get", rb_mod_const_get, -1);

View File

@ -994,6 +994,15 @@ class TestModule < Test::Unit::TestCase
assert_equal([:bClass1], BClass.public_instance_methods(false))
end
def test_undefined_instance_methods
assert_equal([], AClass.undefined_instance_methods)
assert_equal([], BClass.undefined_instance_methods)
c = Class.new(AClass) {undef aClass}
assert_equal([:aClass], c.undefined_instance_methods)
c = Class.new(c)
assert_equal([], c.undefined_instance_methods)
end
def test_s_public
o = (c = Class.new(AClass)).new
assert_raise(NoMethodError, /private method/) {o.aClass1}