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

ruby-changes:70741

From: Shugo <ko1@a...>
Date: Wed, 5 Jan 2022 17:50:21 +0900 (JST)
Subject: [ruby-changes:70741] 54198c7b97 (master): Add Module#refinements and Refinement#refined_class [Feature #12737]

https://git.ruby-lang.org/ruby.git/commit/?id=54198c7b97

From 54198c7b97d3d353f7ac233e0360034b6e7b6cb6 Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@r...>
Date: Wed, 5 Jan 2022 17:47:29 +0900
Subject: Add Module#refinements and Refinement#refined_class [Feature #12737]

---
 NEWS.md                      |  4 ++++
 eval.c                       | 44 +++++++++++++++++++++++++++++++++++++++++++-
 test/ruby/test_refinement.rb | 29 +++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/NEWS.md b/NEWS.md
index 82eb55b8770..de0c5d37a9c 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -28,6 +28,10 @@ Note: We're only listing outstanding class updates. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L28
 
 * Module
     * Module.used_refinements has been added. [[Feature #14332]]
+    * Module#refinements has been added. [[Feature #12737]]
+
+* Refinement
+    * Refinement#refined_class has been added. [[Feature #12737]]
 
 ## Stdlib updates
 
diff --git a/eval.c b/eval.c
index 8103f52fa53..34c5d6ff851 100644
--- a/eval.c
+++ b/eval.c
@@ -1322,7 +1322,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module) https://github.com/ruby/ruby/blob/trunk/eval.c#L1322
     rb_clear_method_cache_all();
 }
 
-/*! \private */
+/*
+ *  call-seq:
+ *     refined_class    -> class
+ *
+ *  Return the class refined by the receiver.
+ */
 VALUE
 rb_refinement_module_get_refined_class(VALUE module)
 {
@@ -1457,6 +1462,41 @@ mod_using(VALUE self, VALUE module) https://github.com/ruby/ruby/blob/trunk/eval.c#L1462
     return self;
 }
 
+
+/*
+ *  call-seq:
+ *     refinements -> array
+ *
+ *  Returns an array of modules defined within the receiver.
+ *
+ *     module A
+ *       refine Integer do
+ *       end
+ *
+ *       refine String do
+ *       end
+ *     end
+ *
+ *     p A.refinements
+ *
+ *  <em>produces:</em>
+ *
+ *     [#<refinement:Integer@A>, #<refinement:String@A>]
+ */
+static VALUE
+mod_refinements(VALUE self)
+{
+    ID id_refinements;
+    VALUE refinements;
+
+    CONST_ID(id_refinements, "__refinements__");
+    refinements = rb_attr_get(self, id_refinements);
+    if (NIL_P(refinements)) {
+        return rb_ary_new();
+    }
+    return rb_hash_values(refinements);
+}
+
 static int
 used_modules_i(VALUE _, VALUE mod, VALUE ary)
 {
@@ -1993,12 +2033,14 @@ Init_eval(void) https://github.com/ruby/ruby/blob/trunk/eval.c#L2033
     rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
     rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
     rb_define_private_method(rb_cModule, "using", mod_using, 1);
+    rb_define_method(rb_cModule, "refinements", mod_refinements, 0);
     rb_define_singleton_method(rb_cModule, "used_modules",
 			       rb_mod_s_used_modules, 0);
     rb_define_singleton_method(rb_cModule, "used_refinements",
                                rb_mod_s_used_refinements, 0);
     rb_undef_method(rb_cClass, "refine");
     rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
+    rb_define_method(rb_cRefinement, "refined_class", rb_refinement_module_get_refined_class, 0);
 
     rb_undef_method(rb_cClass, "module_function");
 
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index c6de9ed958b..017e4e33c1b 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1748,6 +1748,35 @@ class TestRefinement < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1748
     assert_equal [ref::RefB::REF, ref::RefA::REF], ref::Combined::USED_REFS
   end
 
+  def test_refinements
+    int_refinement = nil
+    str_refinement = nil
+    m = Module.new {
+      refine Integer do
+        int_refinement = self
+      end
+
+      refine String do
+        str_refinement = self
+      end
+    }
+    assert_equal([int_refinement, str_refinement], m.refinements)
+  end
+
+  def test_refined_class
+    refinements = Module.new {
+      refine Integer do
+        int_refinement = self
+      end
+
+      refine String do
+        str_refinement = self
+      end
+    }.refinements
+    assert_equal(Integer, refinements[0].refined_class)
+    assert_equal(String, refinements[1].refined_class)
+  end
+
   def test_warn_setconst_in_refinmenet
     bug10103 = '[ruby-core:64143] [Bug #10103]'
     warnings = [
-- 
cgit v1.2.1


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

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