[前][次][番号順一覧][スレッド一覧]

ruby-changes:72073

From: Jeremy <ko1@a...>
Date: Tue, 7 Jun 2022 01:57:48 +0900 (JST)
Subject: [ruby-changes:72073] 7cda7fbbdc (master): Add Module#undefined_instance_methods

https://git.ruby-lang.org/ruby.git/commit/?id=7cda7fbbdc

From 7cda7fbbdc14f4262afaa94cdeb5a5987f1eb01a Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Mon, 6 Jun 2022 09:57:32 -0700
Subject: Add Module#undefined_instance_methods

Implements [Feature #12655]

Co-authored-by: Nobuyoshi Nakada <nobu@r...>
---
 NEWS.md                  |  2 ++
 class.c                  | 24 ++++++++++++++++++++++++
 internal/class.h         |  1 +
 object.c                 |  2 ++
 test/ruby/test_module.rb |  9 +++++++++
 5 files changed, 38 insertions(+)

diff --git a/NEWS.md b/NEWS.md
index 556338bbda..fb43e86e7b 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -112,6 +112,7 @@ Note: We're only listing outstanding class updates. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L112
     * 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. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L236
 ## 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
diff --git a/class.c b/class.c
index 7b91f06229..6db373edc1 100644
--- a/class.c
+++ b/class.c
@@ -1638,6 +1638,15 @@ ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary) https://github.com/ruby/ruby/blob/trunk/class.c#L1638
     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) https://github.com/ruby/ruby/blob/trunk/class.c#L1816
     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
diff --git a/internal/class.h b/internal/class.h
index 70e671b2c2..ae680564a6 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -149,6 +149,7 @@ VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj); https://github.com/ruby/ruby/blob/trunk/internal/class.h#L149
 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);
diff --git a/object.c b/object.c
index a07915606c..951cbdcf3a 100644
--- a/object.c
+++ b/object.c
@@ -4398,6 +4398,8 @@ InitVM_Object(void) https://github.com/ruby/ruby/blob/trunk/object.c#L4398
 		     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);
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index c7245ab2db..3dae3916ff 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -994,6 +994,15 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L994
     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}
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]