ruby-changes:44022
From: shugo <ko1@a...>
Date: Thu, 8 Sep 2016 01:15:50 +0900 (JST)
Subject: [ruby-changes:44022] shugo:r56094 (trunk): * eval.c (rb_mod_s_used_refinements): new method
shugo 2016-09-08 01:15:45 +0900 (Thu, 08 Sep 2016) New Revision: 56094 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56094 Log: * eval.c (rb_mod_s_used_refinements): new method Module.used_refinements. based on the patch by Charlie Somerville. [Feature #7418] [ruby-core:49805] Modified files: trunk/ChangeLog trunk/eval.c trunk/test/ruby/test_refinement.rb Index: eval.c =================================================================== --- eval.c (revision 56093) +++ eval.c (revision 56094) @@ -1311,6 +1311,59 @@ mod_using(VALUE self, VALUE module) https://github.com/ruby/ruby/blob/trunk/eval.c#L1311 return self; } +static int +used_refinements_i(VALUE _, VALUE mod, VALUE ary) +{ + ID id_defined_at; + CONST_ID(id_defined_at, "__defined_at__"); + while (FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) { + rb_ary_push(ary, rb_attr_get(rb_class_of(mod), id_defined_at)); + mod = RCLASS_SUPER(mod); + } + return ST_CONTINUE; +} + +/* + * call-seq: + * used_refinements -> array + * + * Returns an array of all active refinements in the current scope. The + * ordering of modules in the resulting array is not defined. + * + * module A + * refine Object do + * end + * end + * + * module B + * refine Object do + * end + * end + * + * using A + * using B + * p Module.used_refinements + * + * <em>produces:</em> + * + * [B, A] + */ +static VALUE +rb_mod_s_used_refinements(void) +{ + const rb_cref_t *cref = rb_vm_cref(); + VALUE ary = rb_ary_new(); + + while(cref) { + if(!NIL_P(CREF_REFINEMENTS(cref))) { + rb_hash_foreach(CREF_REFINEMENTS(cref), used_refinements_i, ary); + } + cref = CREF_NEXT(cref); + } + + return rb_funcall(ary, rb_intern("uniq"), 0); +} + void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv) { @@ -1645,6 +1698,8 @@ Init_eval(void) https://github.com/ruby/ruby/blob/trunk/eval.c#L1698 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_singleton_method(rb_cModule, "used_refinements", + rb_mod_s_used_refinements, 0); rb_undef_method(rb_cClass, "refine"); rb_undef_method(rb_cClass, "module_function"); Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 56093) +++ test/ruby/test_refinement.rb (revision 56094) @@ -1624,6 +1624,55 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1624 MethodMissing.call_undefined_method end end + + module VisibleRefinements + module RefA + refine Object do + def in_ref_a + end + end + end + + module RefB + refine Object do + def in_ref_b + end + end + end + + module RefC + using RefA + + refine Object do + def in_ref_c + end + end + end + + module Foo + using RefB + USED_REFS = Module.used_refinements + end + + module Bar + using RefC + USED_REFS = Module.used_refinements + end + + module Combined + using RefA + using RefB + USED_REFS = Module.used_refinements + end + end + + def test_used_refinements + ref = VisibleRefinements + assert_equal [], Module.used_refinements + assert_equal [ref::RefB], ref::Foo::USED_REFS + assert_equal [ref::RefC], ref::Bar::USED_REFS + assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_REFS + end private Index: ChangeLog =================================================================== --- ChangeLog (revision 56093) +++ ChangeLog (revision 56094) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Sep 8 01:12:47 2016 Shugo Maeda <shugo@r...> + + * eval.c (rb_mod_s_used_refinements): new method + Module.used_refinements. based on the patch by Charlie + Somerville. [Feature #7418] [ruby-core:49805] + Wed Sep 7 17:50:38 2016 Nobuyoshi Nakada <nobu@r...> * include/ruby/util.h (setenv): remove POSIX-noncompliant -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/