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/