From ad29527920b2a37ee427dc4991ff74d7a2f53e05 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 30 Jun 2023 17:04:52 -0700 Subject: [PATCH] Fix Module#define_method to change visibility when passed existing method body Fixes [Bug #19749] --- test/ruby/test_module.rb | 13 +++++++++++++ vm_method.c | 1 + 2 files changed, 14 insertions(+) diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 75d8d909d7..370b7351c2 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -3163,6 +3163,19 @@ class TestModule < Test::Unit::TestCase end; end + def test_define_method_changes_visibility_with_existing_method_bug_19749 + c = Class.new do + def a; end + private def b; end + + define_method(:b, instance_method(:b)) + private + define_method(:a, instance_method(:a)) + end + assert_equal([:b], c.public_instance_methods(false)) + assert_equal([:a], c.private_instance_methods(false)) + end + def test_define_method_with_unbound_method # Passing an UnboundMethod to define_method succeeds if it is from an ancestor assert_nothing_raised do diff --git a/vm_method.c b/vm_method.c index 3cacc010b8..4cf03fafde 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1250,6 +1250,7 @@ method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, me->def->type, me->def, 0, NULL); if (newme == me) { me->def->no_redef_warning = TRUE; + METHOD_ENTRY_FLAGS_SET(newme, visi, FALSE); } method_added(klass, mid);