1
0
Fork 0
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:
Jeremy Evans 2020-06-01 15:54:47 -07:00
parent 95dc9c07f3
commit b6d6b89615
Notes: git 2020-06-19 00:23:05 +09:00
2 changed files with 36 additions and 1 deletions

View file

@ -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)

View file

@ -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);