* eval.c (rb_using_refinement, rb_mod_using, f_using): clear method

cache only when using is called explicitly.

* test/ruby/test_refinement.rb: related test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37618 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2012-11-11 04:45:31 +00:00
Родитель fc4b6cd25f
Коммит b0c8aeeb9c
3 изменённых файлов: 78 добавлений и 1 удалений

Просмотреть файл

@ -1,3 +1,10 @@
Sun Nov 11 13:41:01 2012 Shugo Maeda <shugo@ruby-lang.org>
* eval.c (rb_using_refinement, rb_mod_using, f_using): clear method
cache only when using is called explicitly.
* test/ruby/test_refinement.rb: related test.
Sun Nov 11 12:56:34 2012 Masaki Matsushita <glass.saga@gmail.com>
* lib/pstore.rb (PStore): fix not to replace ThreadError raised in

3
eval.c
Просмотреть файл

@ -1087,7 +1087,6 @@ rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
module = RCLASS_SUPER(module);
}
rb_hash_aset(cref->nd_refinements, klass, iclass);
rb_clear_cache_by_class(klass);
}
void rb_using_module(NODE *cref, VALUE module);
@ -1153,6 +1152,7 @@ rb_mod_using(VALUE self, VALUE module)
}
rb_hash_aset(using_modules, module, Qtrue);
rb_using_module(cref, module);
rb_clear_cache();
rb_funcall(module, rb_intern("used"), 1, self);
return self;
}
@ -1392,6 +1392,7 @@ f_using(VALUE self, VALUE module)
Check_Type(module, T_MODULE);
rb_using_module(cref, module);
rb_clear_cache();
return self;
}

Просмотреть файл

@ -1,4 +1,5 @@
require 'test/unit'
require_relative 'envutil'
class TestRefinement < Test::Unit::TestCase
class Foo
@ -709,4 +710,72 @@ class TestRefinement < Test::Unit::TestCase
assert_equal("refined", InlineMethodCache::M.module_eval(&f))
assert_equal("original", f.call)
end
module UsingMethodCache
class C
def foo
"original"
end
end
module M1
refine C do
def foo
"M1"
end
end
end
module M2
refine C do
def foo
"M2"
end
end
end
module M
c = C.new
ORIGINAL_FOO = c.foo
using M1
c.foo
using M2
M2_FOO = c.foo
end
end
def test_using_method_cache
assert_equal("original", UsingMethodCache::M::ORIGINAL_FOO)
assert_equal("M2", UsingMethodCache::M::M2_FOO)
assert_in_out_err([], <<-INPUT, %w(:M1 :M2), [])
class C
def foo
"original"
end
end
module M1
refine C do
def foo
:M1
end
end
end
module M2
refine C do
def foo
:M2
end
end
end
c = C.new
using M1
p c.foo
using M2
p c.foo
INPUT
end
end