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

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/

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