summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-19 07:19:33 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-19 07:19:33 +0000
commitc42cf2358c791e43afbb2ef8574c1de62daab9dc (patch)
treea8ca668f46035fd9687c2ebc1bb535da8c890ab3
parenteb97eb08ee4d9791c74c1bd0b62535d7e4169129 (diff)
downloadruby-c42cf2358c791e43afbb2ef8574c1de62daab9dc.tar.gz
merge revision(s) 49480,49493: [Backport #10765]
* vm_method.c (remove_method): When remove refined method, raise a NameError if the method is not defined in refined class. But if the method is defined in refined class, it should keep refined method and remove original method. Patch by Seiei Higa. [ruby-core:67722] [Bug #10765] * class.c (method_entry_i, class_instance_method_list, rb_obj_singleton_methods): should not include methods of superclasses if recur is false. [ruby-dev:48854] [Bug #10826] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@49647 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog18
-rw-r--r--test/ruby/test_refinement.rb52
-rw-r--r--version.h2
-rw-r--r--vm_method.c8
4 files changed, 78 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 544f01d469..322cf57e13 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Thu Feb 19 16:14:04 2015 Shugo Maeda <shugo@ruby-lang.org>
+
+ * class.c (method_entry_i, class_instance_method_list,
+ rb_obj_singleton_methods): should not include methods of
+ superclasses if recur is false. [ruby-dev:48854] [Bug #10826]
+
+Thu Feb 19 16:14:04 2015 Shugo Maeda <shugo@ruby-lang.org>
+
+ * vm_method.c (remove_method): When remove refined
+ method, raise a NameError if the method is not
+ defined in refined class.
+
+ But if the method is defined in refined class,
+ it should keep refined method and remove original
+ method.
+
+ Patch by Seiei Higa. [ruby-core:67722] [Bug #10765]
+
Thu Feb 19 16:07:03 2015 Seiei Higa <hanachin@gmail.com>
* proc.c (rb_obj_singleton_method): Kernel#singleton_method should
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 5837f45d0f..3d703e5a3b 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1310,6 +1310,58 @@ class TestRefinement < Test::Unit::TestCase
end;
end
+ def test_remove_refined_method
+ assert_separately([], <<-"end;")
+ bug10765 = '[ruby-core:67722] [Bug #10765]'
+
+ class C
+ def foo
+ "C#foo"
+ end
+ end
+
+ module RefinementBug
+ refine C do
+ def foo
+ "RefinementBug#foo"
+ end
+ end
+ end
+
+ using RefinementBug
+
+ class C
+ remove_method :foo
+ end
+
+ assert_equal("RefinementBug#foo", C.new.foo, bug10765)
+ end;
+ end
+
+ def test_remove_undefined_refined_method
+ assert_separately([], <<-"end;")
+ bug10765 = '[ruby-core:67722] [Bug #10765]'
+
+ class C
+ end
+
+ module RefinementBug
+ refine C do
+ def foo
+ end
+ end
+ end
+
+ using RefinementBug
+
+ assert_raise(NameError, bug10765) {
+ class C
+ remove_method :foo
+ end
+ }
+ end;
+ end
+
module NotIncludeSuperclassMethod
class X
def foo
diff --git a/version.h b/version.h
index 3f7f856290..9eaea6b815 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.0"
#define RUBY_RELEASE_DATE "2015-02-19"
-#define RUBY_PATCHLEVEL 57
+#define RUBY_PATCHLEVEL 58
#define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 2
diff --git a/vm_method.c b/vm_method.c
index d016fc5c0e..bb13d12b1f 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -766,10 +766,12 @@ remove_method(VALUE klass, ID mid)
if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) ||
!(me = (rb_method_entry_t *)data) ||
- (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF)) {
+ (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
+ UNDEFINED_REFINED_METHOD_P(me->def)) {
rb_name_error(mid, "method `%"PRIsVALUE"' not defined in %"PRIsVALUE,
rb_id2str(mid), rb_class_path(klass));
}
+
key = (st_data_t)mid;
st_delete(RCLASS_M_TBL(klass), &key, &data);
@@ -777,6 +779,10 @@ remove_method(VALUE klass, ID mid)
rb_clear_method_cache_by_class(klass);
rb_unlink_method_entry(me);
+ if (me->def->type == VM_METHOD_TYPE_REFINED) {
+ rb_add_refined_method_entry(klass, mid);
+ }
+
CALL_METHOD_HOOK(self, removed, mid);
}