mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37534 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1c5104ac9c
commit
5836962f48
5 changed files with 35 additions and 17 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
Wed Nov 7 12:49:39 2012 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* misc/ruby-additional.el (ruby-mode-set-encoding): now encoding needs
|
||||
|
|
18
eval.c
18
eval.c
|
@ -1157,21 +1157,6 @@ rb_mod_using(VALUE self, VALUE module)
|
|||
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)
|
||||
{
|
||||
|
@ -1234,12 +1219,11 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||
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);
|
||||
|
|
|
@ -721,6 +721,7 @@ struct RClass {
|
|||
#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;
|
||||
|
|
|
@ -191,6 +191,18 @@ class TestRefinement < Test::Unit::TestCase
|
|||
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
|
||||
|
|
10
vm_method.c
10
vm_method.c
|
@ -167,6 +167,8 @@ rb_free_method_entry(rb_method_entry_t *me)
|
|||
|
||||
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 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type,
|
|||
#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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue