ruby-changes:25477
From: shugo <ko1@a...>
Date: Wed, 7 Nov 2012 13:10:04 +0900 (JST)
Subject: [ruby-changes:25477] shugo:r37534 (trunk): * eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created
shugo 2012-11-07 13:09:51 +0900 (Wed, 07 Nov 2012) New Revision: 37534 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37534 Log: * eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created refinement module, and don't override method_added. * vm_method.c (rb_method_entry_make): check redefinition of optimized methods when a method is added to a refinement module. [ruby-core:48970] [Bug #7290] * test/ruby/test_refinement.rb: related test. Modified files: trunk/ChangeLog trunk/eval.c trunk/include/ruby/ruby.h trunk/test/ruby/test_refinement.rb trunk/vm_method.c Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 37533) +++ include/ruby/ruby.h (revision 37534) @@ -721,6 +721,7 @@ #define RMODULE_M_TBL(m) RCLASS_M_TBL(m) #define RMODULE_SUPER(m) RCLASS_SUPER(m) #define RMODULE_IS_OVERLAID FL_USER2 +#define RMODULE_IS_REFINEMENT FL_USER3 struct RFloat { struct RBasic basic; Index: ChangeLog =================================================================== --- ChangeLog (revision 37533) +++ ChangeLog (revision 37534) @@ -1,3 +1,14 @@ +Wed Nov 7 12:49:39 2012 Shugo Maeda <shugo@r...> + + * eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created + refinement module, and don't override method_added. + + * vm_method.c (rb_method_entry_make): check redefinition of + optimized methods when a method is added to a refinement module. + [ruby-core:48970] [Bug #7290] + + * test/ruby/test_refinement.rb: related test. + Wed Nov 7 11:48:14 2012 Nobuyoshi Nakada <nobu@r...> * misc/ruby-additional.el (ruby-mode-set-encoding): now encoding needs Index: vm_method.c =================================================================== --- vm_method.c (revision 37533) +++ vm_method.c (revision 37534) @@ -167,6 +167,8 @@ static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2); +void rb_redefine_opt_method(VALUE, ID); + static rb_method_entry_t * rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_flag_t noex) @@ -196,6 +198,14 @@ #if NOEX_NOREDEF rklass = klass; #endif + if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) { + ID id_refined_class; + VALUE refined_class; + + CONST_ID(id_refined_class, "__refined_class__"); + refined_class = rb_ivar_get(klass, id_refined_class); + rb_redefine_opt_method(refined_class, mid); + } klass = RCLASS_ORIGIN(klass); mtbl = RCLASS_M_TBL(klass); Index: eval.c =================================================================== --- eval.c (revision 37533) +++ eval.c (revision 37534) @@ -1157,22 +1157,7 @@ return self; } -void rb_redefine_opt_method(VALUE, ID); - static VALUE -refinement_module_method_added(VALUE mod, VALUE mid) -{ - ID id = SYM2ID(mid); - ID id_refined_class; - VALUE klass; - - CONST_ID(id_refined_class, "__refined_class__"); - klass = rb_ivar_get(mod, id_refined_class); - rb_redefine_opt_method(klass, id); - return Qnil; -} - -static VALUE refinement_module_include(int argc, VALUE *argv, VALUE module) { rb_thread_t *th = GET_THREAD(); @@ -1234,12 +1219,11 @@ mod = rb_hash_lookup(refinements, klass); if (NIL_P(mod)) { mod = rb_module_new(); + FL_SET(mod, RMODULE_IS_REFINEMENT); CONST_ID(id_refined_class, "__refined_class__"); rb_ivar_set(mod, id_refined_class, klass); CONST_ID(id_defined_at, "__defined_at__"); rb_ivar_set(mod, id_defined_at, module); - rb_define_singleton_method(mod, "method_added", - refinement_module_method_added, 1); rb_define_singleton_method(mod, "include", refinement_module_include, -1); rb_using_refinement(cref, klass, mod); Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 37533) +++ test/ruby/test_refinement.rb (revision 37534) @@ -191,6 +191,18 @@ assert_equal(0, 1 / 2) end + def test_override_builtin_method_with_method_added + m = Module.new { + refine Fixnum do + def self.method_added(*args); end + def +(other) "overriden" end + end + } + assert_equal(3, 1 + 2) + assert_equal("overriden", m.module_eval { 1 + 2 }) + assert_equal(3, 1 + 2) + end + def test_return_value_of_refine mod = nil result = nil -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/