mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Allow refining a frozen class
Doing so modifies the class's method table, but not in a way that should be detectable from Ruby, so it may be safe to avoid checking if the class is frozen. Fixes [Bug #11669]
This commit is contained in:
parent
95dc9c07f3
commit
b6d6b89615
Notes:
git
2020-06-19 00:23:05 +09:00
2 changed files with 36 additions and 1 deletions
|
@ -2405,6 +2405,39 @@ class TestRefinement < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_refine_frozen_class
|
||||
singleton_class.instance_variable_set(:@x, self)
|
||||
class << self
|
||||
c = Class.new do
|
||||
def foo
|
||||
:cfoo
|
||||
end
|
||||
end
|
||||
foo = Module.new do
|
||||
refine c do
|
||||
def foo
|
||||
:rfoo
|
||||
end
|
||||
end
|
||||
end
|
||||
using foo
|
||||
@x.assert_equal(:rfoo, c.new.foo)
|
||||
c.freeze
|
||||
foo.module_eval do
|
||||
refine c do
|
||||
def foo
|
||||
:rfoo2
|
||||
end
|
||||
def bar
|
||||
:rbar
|
||||
end
|
||||
end
|
||||
end
|
||||
@x.assert_equal(:rfoo2, c.new.foo)
|
||||
@x.assert_equal(:rbar, c.new.bar, '[ruby-core:71391] [Bug #11669]')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
|
|
@ -714,7 +714,9 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
|
|||
}
|
||||
}
|
||||
|
||||
rb_class_modify_check(klass);
|
||||
if (type != VM_METHOD_TYPE_REFINED) {
|
||||
rb_class_modify_check(klass);
|
||||
}
|
||||
|
||||
if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
|
||||
VALUE refined_class = rb_refinement_module_get_refined_class(klass);
|
||||
|
|
Loading…
Reference in a new issue