ruby-changes:44140
From: shugo <ko1@a...>
Date: Fri, 23 Sep 2016 20:46:37 +0900 (JST)
Subject: [ruby-changes:44140] shugo:r56213 (trunk): * eval.c (rb_mod_refine): refine modules as well.
shugo 2016-09-23 20:46:33 +0900 (Fri, 23 Sep 2016) New Revision: 56213 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56213 Log: * eval.c (rb_mod_refine): refine modules as well. [ruby-core:76199] [Feature #12534] Added files: trunk/diff Modified files: trunk/ChangeLog trunk/eval.c trunk/test/ruby/test_refinement.rb trunk/vm_method.c Index: vm_method.c =================================================================== --- vm_method.c (revision 56212) +++ vm_method.c (revision 56213) @@ -439,13 +439,17 @@ make_method_entry_refined(VALUE owner, r https://github.com/ruby/ruby/blob/trunk/vm_method.c#L439 } else { struct { - const struct rb_method_entry_struct *orig_me; + struct rb_method_entry_struct *orig_me; VALUE owner; } refined; rb_vm_check_redefinition_opt_method(me, me->owner); - refined.orig_me = rb_method_entry_clone(me); + refined.orig_me = + rb_method_entry_alloc(me->called_id, me->owner, + me->defined_class || owner, + method_definition_addref(me->def)); + METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me); refined.owner = owner; method_definition_set(me, method_definition_create(VM_METHOD_TYPE_REFINED, me->called_id), (void *)&refined); Index: eval.c =================================================================== --- eval.c (revision 56212) +++ eval.c (revision 56213) @@ -1092,6 +1092,16 @@ rb_mod_prepend(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/eval.c#L1092 return module; } +static void +ensure_class_or_module(VALUE obj) +{ + if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) { + rb_raise(rb_eTypeError, + "wrong argument type %"PRIsVALUE" (expected Class or Module)", + rb_obj_class(obj)); + } +} + static VALUE hidden_identity_hash_new(void) { @@ -1106,7 +1116,7 @@ rb_using_refinement(rb_cref_t *cref, VAL https://github.com/ruby/ruby/blob/trunk/eval.c#L1116 { VALUE iclass, c, superclass = klass; - Check_Type(klass, T_CLASS); + ensure_class_or_module(klass); Check_Type(module, T_MODULE); if (NIL_P(CREF_REFINEMENTS(cref))) { CREF_REFINEMENTS_SET(cref, hidden_identity_hash_new()); @@ -1231,11 +1241,11 @@ add_activated_refinement(VALUE activated https://github.com/ruby/ruby/blob/trunk/eval.c#L1241 /* * call-seq: - * refine(klass) { block } -> module + * refine(mod) { block } -> module * - * Refine <i>klass</i> in the receiver. + * Refine <i>mod</i> in the receiver. * - * Returns an overlaid module. + * Returns a module, where refined methods are defined. */ static VALUE @@ -1255,7 +1265,7 @@ rb_mod_refine(VALUE module, VALUE klass) https://github.com/ruby/ruby/blob/trunk/eval.c#L1265 rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine"); } - Check_Type(klass, T_CLASS); + ensure_class_or_module(klass); CONST_ID(id_refinements, "__refinements__"); refinements = rb_attr_get(module, id_refinements); if (NIL_P(refinements)) { Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 56212) +++ test/ruby/test_refinement.rb (revision 56213) @@ -345,17 +345,64 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L345 assert_equal([:c, :m1, :m2], x) end - def test_refine_module - m1 = Module.new - assert_raise(TypeError) do - Module.new { - refine m1 do + module RefineModule + module M + def foo + "M#foo" + end + + def bar + "M#bar" + end + + def baz + "M#baz" + end + end + + class C + include M + + def baz + "#{super} C#baz" + end + end + + module M2 + refine M do def foo - :m2 + "M@M2#foo" end + + def bar + "#{super} M@M2#bar" + end + + def baz + "#{super} M@M2#baz" end - } + end end + + using M2 + + def self.call_foo + C.new.foo + end + + def self.call_bar + C.new.bar + end + + def self.call_baz + C.new.baz + end + end + + def test_refine_module + assert_equal("M@M2#foo", RefineModule.call_foo) + assert_equal("M#bar M@M2#bar", RefineModule.call_bar) + assert_equal("M#baz C#baz", RefineModule.call_baz) end def test_refine_neither_class_nor_module Index: diff =================================================================== --- diff (revision 0) +++ diff (revision 56213) @@ -0,0 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/diff#L1 +diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb +index 6b6f14c..ee0642c 100755 +--- a/tool/mkconfig.rb ++++ b/tool/mkconfig.rb +@@ -20,7 +20,7 @@ + require "fileutils" + mkconfig = File.basename($0) + +-fast = {'prefix'=>TRUE, 'ruby_install_name'=>TRUE, 'INSTALL'=>TRUE, 'EXEEXT'=>TRUE} ++fast = {'prefix'=>true, 'ruby_install_name'=>true, 'INSTALL'=>true, 'EXEEXT'=>true} + + win32 = /mswin/ =~ arch + universal = /universal.*darwin/ =~ arch Index: ChangeLog =================================================================== --- ChangeLog (revision 56212) +++ ChangeLog (revision 56213) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Sep 23 20:36:05 2016 Shugo Maeda <shugo@r...> + + * eval.c (rb_mod_refine): refine modules as well. + [ruby-core:76199] [Feature #12534] + Fri Sep 23 20:19:09 2016 Akinori MUSHA <knu@i...> * man/ruby.1: Update the paragraphs in "Rich Libraries" which -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/